Ios 如何同步打开/创建UIManagedDocument?

Ios 如何同步打开/创建UIManagedDocument?,ios,objective-c-blocks,uimanageddocument,Ios,Objective C Blocks,Uimanageddocument,如标题中所述,我希望同步打开UIManagedDocument,也就是说,我希望我的执行等待打开完成。我仅在主线程上打开文档 当前要打开的API使用块 [UIManagedDocument openWithCompletionHandler:(void (^)(BOOL success))]; 在中提到的锁用法在除主线程之外的线程上运行良好。如果我在主线程上使用锁,它会冻结应用程序的执行 任何建议都会有帮助。谢谢。首先,让我说我强烈反对这样做。您的主线程只是等待,在等待调用完成时什么也不做。在

如标题中所述,我希望同步打开
UIManagedDocument
,也就是说,我希望我的执行等待打开完成。我仅在主线程上打开文档

当前要打开的API使用块

[UIManagedDocument openWithCompletionHandler:(void (^)(BOOL success))];
在中提到的锁用法在除主线程之外的线程上运行良好。如果我在
主线程上使用锁,它会冻结应用程序的执行


任何建议都会有帮助。谢谢。

首先,让我说我强烈反对这样做。您的主线程只是等待,在等待调用完成时什么也不做。在某些情况下,如果应用程序在主线程上没有响应,系统将终止应用程序。这是非常不寻常的

我想应该由你来决定何时/如何使用各种编程工具

这个正是你想要的。。。阻塞主线程,直到完成处理程序运行。再一次,我不建议这样做,但是,嘿,这是一个工具,我会采取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);
}
另一个选项是执行run循环。但是,这并不是真正的同步,因为运行循环实际上会处理其他事件。我在一些单元测试中使用了这种技术。它与上面的类似,但仍然允许在主线程上发生其他事情(例如,完成处理程序可以调用主队列上的操作,在前面的方法中可能不会执行该操作)

还有其他的方法,但这些方法很简单,容易理解,而且非常突出,所以很容易知道你在做一些非正统的事情

我还应该注意到,除了测试之外,我从来没有遇到过这样做的好理由。您可以使代码死锁,而不从主运行循环返回是一个很滑的斜坡(即使您自己手动执行它-请注意,调用的代码仍在等待,再次运行循环可能会重新输入该代码,或导致其他问题)

异步API很棒。在使用其他线程时,条件变量方法或对并发队列使用屏障是同步的合理方法。同步主线程与您应该做的相反


祝你好运。。。确保你登记了你的枪,并且总是带着你的隐藏武器许可证。这当然是狂野的西部。约翰·卫斯理·哈登(John Wesley Harden)总是在寻找枪战。

…谢谢你抽出时间。我尝试搜索旧的API打开文档,没有块。任何想法,这是如何实现的?UIManagedDocument是一个相对较新的接口,我认为它从未有过同步API。在内部,它有两个ManagedObjectContext对象。。。一个在主线程上,一个使用私有调度队列。所有IO操作都发生在后台,因此类的性质决定了使用异步API。在块之前,异步API使用委托或通知让调用方知道操作何时完成。当我尝试以下代码时,这不起作用:\uu block BOOL waitingOnCompletionHandler=YES;[\u managedDocument openWithCompletionHandler:^(BOOL success){if(success){DLog(@“打开文档成功!”);self.managedObjectContext=\u managedDocument.managedObjectContext;waitingOnCompletionHandler=NO;}];虽然(waitingOnCompletionHandler){usleep(USEC_PER_SEC/10)}主线程永远卡在那里…@zolibra-您陷入死锁的原因是
completionHandler
在您的情况下实际上有工作要做,它需要主线程来完成。因此,它在等待已被阻止的主线程时被阻止。这就是为什么人们强烈反对这种做法的部分原因。
__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];
}