如标题中所述,我想同步打开UIManagedDocument
,即我希望我的执行等到打开完成。我只在mainThread上打开文档。
要打开的当前API使用块
[UIManagedDocument openWithCompletionHandler:(void (^)(BOOL success))];
link中提到的锁用法在主线程以外的线程上运行良好。如果我在mainThread
上使用锁定,它会冻结app的执行。
任何建议都会有所帮助。感谢。
答案 0 :(得分:2)
首先,请允许我说强烈反对这样做。您的主线程只是等待,并在等待呼叫完成时不执行任何操作。在某些情况下,如果系统在主线程上没有响应,系统将终止您的应用。这非常不寻常。
我想你应该决定何时/如何使用各种编程工具。
这个完全符合您的要求...阻止主线程直到完成处理程序运行。再一次,我不建议这样做,但是,嘿,这是一个工具,我将采取NRA的立场:枪不会杀人......
__block BOOL waitingOnCompletionHandler = YES;
[object doSomethingWithCompletionHandler:^{
// Do your work in the completion handler block and when done...
waitingOnCompletionHandler = NO;
}];
while (waitingOnCompletionHandler) {
usleep(USEC_PER_SEC/10);
}
另一种选择是执行运行循环。但是,这并不是真正的同步,因为运行循环实际上会处理其他事件。我在一些单元测试中使用过这种技术。它类似于上面的内容,但仍允许在主线程上发生其他事情(例如,完成处理程序可能会调用主队列上的操作,这可能无法在前一个方法中执行)。
__block BOOL waitingOnCompletionHandler = YES;
[object doSomethingWithCompletionHandler:^{
// Do your work in the completion handler block and when done...
waitingOnCompletionHandler = NO;
}];
while (waitingOnCompletionHandler) {
NSDate *futureTime = [NSDate dateWithTimeIntervalSinceNow:0.1];
[[NSRunLoop currentRunLoop] runUntilDate:futureTime];
}
还有其他方法,但这些方法很简单,易于理解,并且像拇指一样伸出,因此很容易知道你正在做一些非正统的事情。
我还应该注意到,除了测试以外,我从来没有遇到过这么做的好理由。您可以使代码死锁,而不是从主运行循环返回是一个滑坡(即使您自己手动执行它 - 请注意,调用您的内容仍在等待并再次运行循环可能会重新输入该代码,或导致其他一些问题)。
异步API很棒。条件变量方法或使用并发队列的障碍是使用其他线程时同步的合理方法。同步主线程与你应该做的相反。
祝你好运......并确保你注册你的枪支,并随身携带你的隐藏武器许可证。这当然是狂野的西部。总有一个John Wesley Harden在那里寻找枪战。