gpt4 book ai didi

objective-c - 关于 Swift 中的同步作用域

转载 作者:搜寻专家 更新时间:2023-10-31 22:45:56 26 4
gpt4 key购买 nike

Objective-C :

@synchronized {
return;
}
NSLog(@"This line of code does not run.");

Objective-C's @synchronized is a language-level directive and does not introduce a new function scope.

swift :

synchronized {
return
}
print("This line of code does run.")


func synchronized(lock: AnyObject, @noescape closure: () -> Void) {
objc_sync_enter(lock)
closure()
objc_sync_exit(lock)
}

Synchronized uses closures which do introduce a function scope.

问题:

我可以在 Swift 中做同样的事情吗?不引入新的功能范围。

真正的问题

public func stopRecording() {

synchronized(self) {
guard status == .Recording else { return }
status = .StoppingRecording
}

// Many somethings need to do, and I don`t want to write into the closure.
finishRecording()
......
......
......
}

解决方法:

if (synchronized(self) { return true }) {
return
}

print(@"This line of code does not run.")


func synchronized(lock: AnyObject, @noescape closure: () -> Bool) -> Bool {
objc_sync_enter(lock)
defer {
objc_sync_exit(lock)
}
return closure()
}

有人有优雅的解决方案吗?

最佳答案

我只是整理了一个还算不错的解决方案。我们不能引入不引入新范围的自定义语言构造,因此我们需要使用现有的一个。 if 语句应该适用于此。我为此创建了一个小类,它只做一件事:锁定给定对象并检查 unlock 方法在它释放之前是否被调用(以及一些调试添加):

final class LockingManager {
let obj: AnyObject

let file: StaticString
let line: UInt

var locked = true

init(obj: AnyObject, file: StaticString, line: UInt) {
self.obj = obj
self.file = file
self.line = line
objc_sync_enter(obj)
}

func unlock() {
objc_sync_exit(obj)
locked = false
}

deinit {
precondition(!locked, "Object \(obj) not unlocked", file: file, line: line)
}
}

像这样的函数:

func lock(obj: AnyObject, file: StaticString = #file, line: UInt = #line) -> (() -> Void)? {
return LockingManager(obj: obj, file: file, line: line).unlock
}

我们可以这样使用它:

if let unlock = lock(obj: self) {
defer { unlock() }
// Do stuff
}

因为方法从不返回 nil,所以您永远不需要 else 部分。由于持有对 LockingManager 的唯一引用的 unlock 方法仅在 if 语句中可用,因此在语句之后 LockingManager 被释放.释放时,它会检查 unlock 方法是否被调用,如果没有,则抛出错误。

我知道这不是一个非常好的解决方案,但它确实有效,因为它没有引入新的范围(并且另外检查正确使用)。

另一个解决方案是只使用简单的函数调用和一个 do block :

do {
objc_sync_enter(self)
defer { objc_sync_exit(self) }

// Do stuff
}

我个人更喜欢第二种方法(有一些更好命名的函数),因为它的作用更加清晰。

关于objective-c - 关于 Swift 中的同步作用域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38163604/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com