Rob*_*ert 3 multithreading core-data ios
我在文档中发现了类似的内容performBlockAndWait:
可以安全地以可重入的方式调用此方法。
我的问题是,这是否意味着当我在单个上下文中像这样调用它时,它永远不会导致死锁?:
NSManageObjectContext *context = ...
[context performBlockAndWait:^{
// ... some stuff
[context performBlockAndWait:^{
}];
}];
Run Code Online (Sandbox Code Playgroud)
您可以使用一小段代码自己尝试一下;)
但事实是,它不会陷入僵局。
我怀疑,内部实现使用队列特定令牌来识别代码执行的当前队列(请参阅dispatch_queue_set_specific和dispatch_queue_get_specific)。
如果它确定当前正在执行的代码在其自己的私有队列或子队列上执行,它会简单地绕过同步提交块(这会导致死锁),而是直接执行它。
我的一个可能的实现如下:
func executeSyncSafe(f: () -> ()) {
if isSynchronized() {
f()
} else {
dispatch_sync(syncQueue, f)
}
}
func isSynchronized() -> Bool {
let context = UnsafeMutablePointer<Void>(Unmanaged<dispatch_queue_t>.passUnretained(syncQueue).toOpaque())
return dispatch_get_specific(&queueIDKey) == context
}
Run Code Online (Sandbox Code Playgroud)
队列可能是这样创建的:
private var queueIDKey = 0 // global
init() {
dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL,
QOS_CLASS_USER_INTERACTIVE, 0))
let context = UnsafeMutablePointer<Void>(Unmanaged<dispatch_queue_t>.passUnretained(syncQueue).toOpaque())
dispatch_queue_set_specific(syncQueue, &queueIDKey, context, nil)
}
Run Code Online (Sandbox Code Playgroud)
dispatch_queue_set_specific将令牌(此处context只是队列的指针值)与该队列的某个键相关联。之后,您可以尝试为指定键的任何队列检索该令牌,并检查当前队列是同一个队列还是子队列。如果这是真的,则绕过调度到队列,而是f直接调用该函数。
| 归档时间: |
|
| 查看次数: |
274 次 |
| 最近记录: |