- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我之前已经看过这个问题,但是在我的情况下,所有解决方案似乎都没有影响,这是:
我的应用程序使用三个ManagedObjectContexts:
1)在全局(后台)队列上创建具有NSPrivateQueueConcurrencyType并且没有父上下文的“diskManagedObjectContext”,并将其用于在后台线程上将上下文更改写入磁盘(持久存储):
-(NSManagedObjectContext *)diskManagedObjectContext
{
if (! _diskManagedObjectContext)
{
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
^{
_diskManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
_diskManagedObjectContext.persistentStoreCoordinator = self.ircManagedObjectLibrary.persistentStoreCoordinator;
});
}
return _diskManagedObjectContext;
}
-(NSManagedObjectContext *)mainManagedObjectContext
{
if (! _mainManagedObjectContext)
{
_mainManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
_mainManagedObjectContext.undoManager = nil;
_mainManagedObjectContext.parentContext = self.diskManagedObjectContext;
}
return _mainManagedObjectContext;
}
-(NSManagedObjectContext *)backgroundManagedObjectContext
{
if (! _backgroundManagedObjectContext)
{
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
^{
_backgroundManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
_backgroundManagedObjectContext.undoManager = nil;
_backgroundManagedObjectContext.parentContext = self.mainManagedObjectContext;
});
}
return _backgroundManagedObjectContext;
}
-(BOOL)saveChanges:(NSError **)error
{
__block BOOL successful = NO;
*[DEADLOCKS HERE]* [self.managedObjectContext performBlockAndWait: *[SYNCHRONOUS]*
^{
NSError *internalError = nil;
// First save any changes on the managed object context of this ManagedObjectLibrarian. If the context has a parent, this does not write changes to disk but instead simply pushes the changes to the parent context in memory, and so is very fast.
successful = [_managedObjectContext save:&internalError];
if (successful)
{
// If successful, then if the context of this ManagedObjectLibrarian has a parent with private queue concurrency (which only the app delegate's mainIrcManagedObjectLibrarian does), save the changes on that parent context, which if it does not itself have a parent will write the changes to disk. Because this write is performed as a block operation on a private queue, it is executed in a non-main thread.
if (_managedObjectContext.parentContext)
{
[_managedObjectContext.parentContext performBlock: *[ASYNCHRONOUS]*
^{
if (_managedObjectContext.parentContext.concurrencyType == NSPrivateQueueConcurrencyType)
{
NSError *parentError = nil;
BOOL parentSuccessful = [_managedObjectContext.parentContext save:&parentError];
[Error handling, etc.]
[self.managedObjectContext performBlockAndWait: *[SYNCHRONOUS]*
[self.backgroundManagedObjectLibrarian saveChanges:nil];
[self.dataSourceProperties.managedObjectContext performBlock: *[ASYNCHRONOUS]*
^{
self.dataSourceProperties.dataArchiving.isEnabled = [NSNumber numberWithBool:_dataArchivingIsEnabled];
*[DEADLOCKS HERE]* [self.dataSourceProperties.managedObjectContext save:nil];
}];
最佳答案
您的实现存在许多问题。
diskManagedObjectContext
和backgroundManagedObjectContext
dispatch_barrier_sync
返回值,并使用dispatch_barrier_async
写入值。 saveChanges
方法应该异步- (void) saveContextChainWithContext:(NSManagedObjectContext*)context
completion:(void (^)(NSError*error))completion
{
[context performBlock:^{
NSError* error;
if ([context save:&error]) {
NSManagedObjectContext* ctx = [context parentContext];
if (ctx) {
dispatch_async(dispatch_get_global(0,0), ^{
[self saveContextChainWithContext:ctx completion:completion];
});
}
else {
if (completion) {
completion(nil);
}
}
}
else {
if (completion) {
completion(error);
}
}
}];
}
关于ios - ManagedObjectContext performBlock(AndWait)死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22947026/
我有类似下面的代码: ... id: myComponent signal updateState() property variant modelList: [] Repeater { mo
我正在处理一些我无法展示的私有(private)代码,但我已经制作了一些示例代码来描述我的问题: 主.c: #include #include #include #include typede
这个问题在这里已经有了答案: 关闭10 年前。 Possible Duplicate: what are the differences in die() and exit() in PHP? 我想
在编写 Perl 模块时,在模块内部使用 croak/die 是一个好习惯吗? 毕竟,如果调用者不使用 eval block ,模块可能会使调用它的程序崩溃。 在这些情况下,最佳做法是什么? 最佳答案
我有一些搜索线程正在存储结果。我知道当线程启动时,JVM native 代码会代理在操作系统上创建新 native 线程的请求。这需要 JVM 之外的一些内存。当线程终止并且我保留对它的引用并将其用作
我刚刚花了很多时间调试一个我追溯到 wantarray() 的问题。 .我已将其提炼为这个测试用例。 (忽略 $! 在这种情况下不会有任何有用信息的事实)。我想知道为什么wantarray在第二个示例
我看到一些代码是这样做的: if(something){ echo 'exit from program'; die; } ...more code 和其他只使用 die 的人: if
我正在尝试将此表格用于: 如果任何 $_POST 变量等于任何其他 $_POST 变量抛出错误。 如果只有几个,那不是问题,但我有大约 20 个左右所以如果我想这样做,我将不得不像这样 但这
每次我运行: hadoop dfsadmin -report 我得到以下输出: Configured Capacity: 0 (0 KB) Present Capacity: 0 (0 KB) DFS
我是一名优秀的程序员,十分优秀!