Lock
No concurrency, no encoding. As long as we talk about multithreading or concurrent code, it may be difficult for us to bypass the discussion of locks. Simply put, in order to securely access the same resource in different threads, we need these access sequences. There are many lock methods in Cocoa and Objective-C, but the most common method in daily development is @ synchronized. This keyword can be used to modify a variable, and automatically add and remove mutex locks. In this way, the variable is not changed by other threads within the scope of its function. For example, if we have a method that accepts parameters and requires this method to be thread-safe, we need to lock the parameters:
-(Void) myMethod :( id) anObj {
@ Synchronized (anObj ){
// AnObj in brackets will not be changed by other threads
}
}
If there is no lock, the behavior of this method may be unpredictable once the anObj content is modified by other threads.
However, locking and unlocking both consume a certain amount of performance, so we are unlikely to add a lock to all methods. In addition, the multi-threaded part of an app is limited, and we do not need to add a lock for everything. Too many locks are meaningless, and for multi-threaded programming, there may be many traps such as deadlocks, and it is difficult to debug. Therefore, when using multithreading, we should try to keep simplicity as the top priority.
Let's get back to @ synchronized. Although this method is easy to use, it is unfortunate that it does not exist in Swift (or temporarily. In fact, @ synchronized called the objc_sync_enter and objc_sync_exit methods in objc_sync, and added some exception judgments. Therefore, in Swift, if we ignore the exceptions and want to lock a variable, we can write as follows:
Func myMethod (anObj: AnyObject !) {
Objc_sync_enter (anObj)
// AnObj between enter and exit will not be changed by other threads
Objc_sync_exit (anObj)
}
Furthermore, if we like the previous form, we can even write a Global method and accept a closure to encapsulate objc_sync_enter and objc_sync_exit:
Func synchronized (lock: AnyObject, closure: ()-> ()){
Objc_sync_enter (lock)
Closure ()
Objc_sync_exit (lock)
}
Combined with the language features of Swift's trailing closure, it is similar to Objective-C when used:
Func myMethodLocked (anObj: AnyObject !) {
Synchronized (anObj ){
// AnObj in brackets will not be changed by other threads
}
}