Closed amorde closed 2 years ago
Thanks, @amorde for the interesting suggestion! Since this is a relatively easy change, this will be addressed in the converter at the nearest time.
It may take more time for these changes to be included in the Offline version - our macOS desktop developer is in Ukraine and is currently unavailable :(
P.S. Just wondering if such a solution using defer
keyword will be acceptable to you?
This might be easier from the code generation standpoint (don't need to introduce a returnValue
variable):
import Foundation
private var _cachedValues: [AnyHashable : Any]?
class SomeObject: NSObject {
class func someSharedValue() -> String? {
objc_sync_enter(_cachedValues)
defer { objc_sync_exit(_cachedValues) }
return _cachedValues?["SomeKey"] as? String
}
}
Yeah that makes sense! As long as the code being converted has the return
statement inside the @synchronize(objc)
block that should work. Other cases would need to be handled differently.
@amorde I hear what you say about the return
statement.
We'll see whatever is easier from the implementation standpoint - either your suggestion or mine using the defer { }
statement.
@amorde I just came across this article about pitfalls of using objc_sync_enter / objc_sync_exit. I still think that your suggested changes make sense, but please confirm if you are aware of possible deadlocks with your suggested approach.
P.S. Fixed (will be available since the next converter update).
Output for your sample:
import Foundation
private var _cachedValues: [AnyHashable : Any]?
class SomeObject: NSObject {
class func someSharedValue() -> String? {
objc_sync_enter(_cachedValues)
defer { objc_sync_exit(_cachedValues) }
return _cachedValues?["SomeKey"] as? String
}
}
Another sample (without a return
statement inside the @synchronized()
block.
Input:
@synchronized(myLockObject) {
NSLog("Hello World");
}
Output:
objc_sync_enter(myLockObject)
print("Hello World")
objc_sync_exit(myLockObject)
Input:
Output:
Using
objc_sync_enter
andobjc_sync_exit
will maintain the previous behavior and also avoid creating a large number ofDispatchQueue
instances: