This profile
- Topic: Apple announced to suspend sales of its products in Russia and shut down some functions
- Tips: SwiftLint integration with SPM
- Interview module: How is Swift weak implemented?
- Good blog: Scaffolding /CLI introduction in iOS projects
- Learning materials: Swift implementation of the design pattern
- Development tools: NginxEdit: Nginx online configuration tool
This topic
@ zhangferry:
Apple has announced that it is suspending sales of its products and shutting down some functions in Russia
Apple said on March 1 that it had stopped selling its products in Russia, according to CNBC. Meanwhile, two apps belonging to Russian state media have been removed and Apple Pay and other functions have been restricted in the region. Here’s what an Apple spokesperson said:
We have taken a number of actions in response to the invasion. We have paused all product sales in Russia. Last week, we stopped all exports into our sales channel in the country. Apple Pay and other services have been limited. RT News and Sputnik News are no longer available for download from the App Store outside Russia. And we have disabled both traffic and live incidents in Apple Maps in Ukraine as a safety and precautionary measure for Ukrainian citizens.
There are a lot of people say that we should support domestic phones, but domestic phones are also a magic version of Android, which is not as firmly controlled as Apple, nor is it completely controllable. Not only Apple, but also Google, Twitter, TSMC, Intel, and even Github and React are all boycotting Russia these days. It is alarming that “technology knows no borders” has become a complete lie.
Modern war is complicated. It is not just guns, but also accompanied by all kinds of public opinion war and information war, and the initiative of information war is held by the party with core technology. Looking back at Russia, could something similar happen to us? The thinking from this incident is that it is not enough just to storm a community message board with words, but to break the monopoly and continuously improve our own core technical capabilities. Science and technology power, we should strengthen!
The development of Tips
Get the environment variable Key corresponding to Build Setting
zhangferry
There are many configuration items in the Build setting of Xcode, and these configuration items have corresponding environment variables. When we want to customize the script, we need to know which Key of the corresponding environment variable is easy to set. For example, Header Search Paths
The corresponding Key is HEADER_SEARCH_PATHS. How about this Key? In addition to looking up relevant information online, we can also get it through Xcode.
Method 1 (courtesy of @Codestar)
Select the configuration item, expand the right sidebar, and click the help button to see the description of the configuration and the corresponding environment variable name.
Method 2
Select the configuration, hold down the Option key, and double-click the configuration. A help card describing the Option appears, as shown in the help sidebar above.
SwiftLint integration with SPM
Edited by FBY Zhan Fei
SwiftLint introduction
SwiftLint is a utility for implementing the Swift style. Integrating SwiftLint is easy during the Xcode project build phase, which automatically triggers SwiftLint when the project is compiled.
Unfortunately, SwiftLint cannot be easily integrated with Swift Packages, which does not have a build phase and does not automatically run scripts.
Here’s how to use the Post Action script in Xcode to automatically trigger SwiftLint after a successful compilation of the Swift Package.
Succeedspostaction. sh is a bash script used for the “Succeeds” publish operation in Xcode. This script will automatically trigger SwiftLint when you compile a Swift package.
SwiftLint installation
-
Download the script succeedspostAction.sh on Mac.
-
Make sure the script has the appropriate permissions by running chmod 755 succeedspostAction.sh.
-
To use custom SwiftLint rules, add the.swiftlint.yml file next to the script.
-
Start Xcode 13.0 or later
-
Open Preferences > Locations and make sure the Command Line Tools is set to the Xcode version
-
Choose Preferences > Behaviors > Succeeds
-
Select the script succeedspostAction.sh
That’s it: SucceedspostAction.sh runs SwiftLint every time a Swift package is compiled.
demo
There are some problems
Post action scripts running in Xcode cannot add logs, warnings, or errors to Xcode build results. Thus, succeedspostAction.sh opens a text file in Xcode as a new window containing a list of SwiftLint reports. No deep integration makes it easy to jump to SwiftLint alerts.
Swift, 5.6
Note that since SE-0303: Package Manager Extensible Build Tools, Swift 5.6 (fashion not available at the time of writing) may be helpful. After the SE-0303 integration, this script is no longer required.
Reference: Swift utility – SwiftLint – Swift community
Parsing the interview
Edited by JY
How is Swift weak implemented?
In Swift, you also have a SideTable, which is created for objects that need it, and the system allocates a new chunk of memory for the target object to hold additional information about that object.
The object will have a pointer to the SideTable, and the SideTable will have a pointer back to the original object. In order not to use extra memory, weak references are only used when creating weak references. The reference count of the object is put into the newly created SideTable, and then the empty space is used to store the address of SideTable. A flag bit is used to distinguish whether the object has SideTable.
class JYObject {
var age :Int = 18
var name:String = "JY"
}
var t = JYObject(a)weak var t2 = t
print("--")
Copy the code
We make a breakpoint at print and look at the T2 object
(LLDB) Po T2 ▿ Optional<JYObject> ▿ some: <JYObject: 0x6000001a9710> (LLDB) x/8gx 0x6000001a9710 0x6000001a9710: 0x0000000100491e18 0xc0000c00001f03dc 0x6000001a9720: 0x0000000000000012 0x000000000000594a 0x6000001a9730: 0xe200000000000000 0x0000000000000000 0x6000001a9740: 0x00007efd22b59740 0x000000000000009c (lldb)Copy the code
By looking at the assembly and defining a weak variable, the compiler automatically calls swift_weakInit function, which is called by WeakReference. Weak field automatically generates WeakReference object during compiler declaration.
WeakReference *swift::swift_weakInit(WeakReference *ref, HeapObject *value) {
ref->nativeInit(value);
return ref;
}
void nativeInit(HeapObject *object) {
auto side = object ? object->refCounts.formWeakReference() : nullptr;
nativeValue.store(WeakReferenceBits(side), std::memory_order_relaxed);
}
template <>
HeapObjectSideTableEntry* RefCounts<InlineRefCountBits>::formWeakReference() {
// Create a Side Table
auto side = allocateSideTable(true);
if (side)
// Add a weak reference
return side->incrementWeak(a);else
return nullptr;
}
Copy the code
Let’s look at the allocateSideTable method, how to create a SideTable
template <>
HeapObjectSideTableEntry* RefCounts<InlineRefCountBits>::allocateSideTable(bool failIfDeiniting) {
//1. Get the old reference count
auto oldbits = refCounts.load(SWIFT_MEMORY_ORDER_CONSUME);
// Check if there is a SideTable,
if (oldbits.hasSideTable()) {
// Already have a side table. Return it.
return oldbits.getSideTable(a); }else if (failIfDeiniting && oldbits.getIsDeiniting()) {
// Already past the start of deinit. Do nothing.
return nullptr;
}
// Preflight passed. Allocate a side table.
// FIXME: custom side table allocator
//2. Create a HeapObjectSideTableEntry instance object with HeapObject
HeapObjectSideTableEntry *side = new HeapObjectSideTableEntry(getHeapObject());
//3. Give the address of the created instance object to InlineRefCountBits (RefCountBitsT)
auto newbits = InlineRefCountBits(side);
do {
if (oldbits.hasSideTable()) {
// Already have a side table. Return it and delete ours.
// Read before delete to streamline barriers.
auto result = oldbits.getSideTable(a);delete side;
return result;
}
else if (failIfDeiniting && oldbits.getIsDeiniting()) {
// Already past the start of deinit. Do nothing.
return nullptr;
}
// Store the original reference count
side->initRefCounts(oldbits);
} while(! refCounts.compare_exchange_weak(oldbits, newbits,
std::memory_order_release,
std::memory_order_relaxed));
return side;
}
Copy the code
To summarize what we did above
HeapObjectSideTableEntry creates a HeapObjectSideTableEntry instance object 3. Give the address of the created instance object to InlineRefCountBits, also known as RefCountBitsT.
After constructing the Side Table, the RefCountBitsT in the object is not the original reference count, but a pointer to the Side Table, however since they are actually uint64_t, a method is needed to distinguish them. The constructor for InlineRefCountBits can be used to distinguish between them:
/ / weak references
LLVM_ATTRIBUTE_ALWAYS_INLINE
RefCountBitsT(HeapObjectSideTableEntry* side)
: bits((reinterpret_cast<BitsType>(side) >> Offsets::SideTableUnusedLowBits)
| (BitsType(1) << Offsets::UseSlowRCShift)
| (BitsType(1) << Offsets::SideTableMarkShift))
{
assert(refcountIsInline);
}
Copy the code
The weak-reference method offsets the created address and stores it in memory.
SideTableUnusedLowBits = 3, so, in this process, the side passed in is shifted 3 bits to the right, and the next two bits are 62 bits and 63 bits marked as 1
Let’s look at the structure of the heapObject TableEntry
class HeapObjectSideTableEntry {
// FIXME: does object need to be atomic?
std::atomic<HeapObject*> object;
SideTableRefCounts refCounts;
public:
HeapObjectSideTableEntry(HeapObject *newObject)
: object(newObject), refCounts() {}Copy the code
Let’s try undoing the weak reference count:
0xC0000C00001F03DC62 and 63 bits clear 0 get the address 0xC00001F03DC of the HeapObjectSideTableEntry instance object
So since it’s moved 3 bits to the right, so I’m going to move 3 bits to the left to restore it, HeapObjectSideTableEntry moved 3 bits to the left to get 0x10062AFE0
0x6000001a9710
That’s the address of the instance object0x0000000000000002
It’s weak reference counting where weak reference is zero2
The reason is thatSideTableRefCountBits
Initialization time from1
start
The life cycle of the Side Table is separated from the object. When the strong reference count is 0, only the HeapObject is released, but the Side Table is not released. Only after all weak references are released or relevant variables are set to nil, So Side Table can be released.
Good blog
I am xiong Da
The topic of this excellent blog is scaffolding /CLI. At the beginning of the project, the scaffolding tool will help you set up the shelves and generate some basic code. The presence of scaffolding helps teams unify architectural styles and speed up project development.
1. Build your own scaffolding /CLI knowledge from 0 — from nuggets: Old IT squad leader
I am xiong Da: How to generate scaffolding? In this article, the author builds a scaffold from scratch using NodeJS. Each step is detailed, and introduces the popular scaffolding tool library.
IOS automation tool Gckit CLI — from blog: SeongBrave
I am Xiong: In the project development, everyone’s level is uneven, the code style is different, especially when new people join the team, the adaptation period will be longer. Is it possible for new students to develop as quickly as their old classmates, but with similar code styles? This is how Gckit CLI was born, and after reading the previous article you can tweak the library to build your own automation tools
3. Swift + RxSwift MVVM modular project practice — from nuggets: SeongBrave
This article is a summary of Gckit author’s practice. It mainly explains some project practices to maximize development efficiency through CocoaPods combined with GCKit-CLI.
4, iOS automation program attached script — from nuggets: I am xiong Da
I am Bear: Different PC development environments are different, different environment can cause various problems, for example, CocoaPods version is different, some libraries can not download,.lock file update frequently, etc. This article describes how to unify the development environment and the use of automated scripts that you can put into your scaffolding tools. The article ends with a whimsy about scaffolding tools.
Learning materials
Mimosa
Design patterns implemented by Swift
Address: oldbird. Run/design – patt…
A design pattern tutorial implemented by Swift language. The examples of design patterns are clear, and the code is simple and easy to understand. Most of the examples have UML diagrams to help understand, and there are also some summaries and generalizations of the differences and connections between different design patterns, which are very good resources for learning design patterns.
Tools recommended
CoderStar
nginxedit
Address: www.nginxedit.cn/
Software status: Free
Software Introduction:
Nginx online configuration generation tool, the easiest way to configure a high performance, secure and stable Nginx server.
About us
IOS Fish weekly, mainly share the experience and lessons encountered in the development process, high-quality blog, high-quality learning materials, practical development tools, etc. The weekly warehouse is here: github.com/zhangferry/… If you have a good content recommendation, you can submit it through the way of issue. You can also apply to be our resident editor to maintain the weekly. Also can pay attention to the public number: iOS growth road, backstage click into the group communication, contact us, get more content.
Phase to recommend
IOS Fishing Weekly 44th issue
IOS Fishing Weekly 43
IOS Fishing Week 42nd issue
IOS fishing weekly 41 issue