objective-c - NSManagedObjectContext 和 performBlock,iOS 8 上的变化?

标签 objective-c core-data

我有一个旧项目(从 iOS 7 开始),代码很简单:

在 AppDelegate 中我创建了 managedObjectContext:

- (NSManagedObjectContext *)managedObjectContext {
    // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (!coordinator) {
        return nil;
    }
    _managedObjectContext = [[NSManagedObjectContext alloc] init];
    [_managedObjectContext setPersistentStoreCoordinator:coordinator];
    return _managedObjectContext;
}

然后,我在 View Controller 中执行更新操作:

    [context performBlock:^{
        [context deleteObject:anObject];

        NSError *error = nil;
        if (![context save:&error])
        {
            NSLog(@"Error saving context");
        }
    }];

我确定此代码在 iOS 7.0 上运行正常,但在 iOS 8 上调用 performBlock: 时崩溃并出现此错误:

Can only use -performBlockAndWait: on an NSManagedObjectContext that was created with a queue.

我可以像这样更改 NSManagedObjectContext 实例的 init 方法来解决错误:

_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];

但我不明白为什么这种行为会改变。在 NSManagedObjectContext 的文档中,您可以阅读:

A consequence of this is that a context assumes the default owner is the thread or queue that allocated it—this is determined by the thread that calls its init method.

因此,在我的第一个示例中,使用简单的 init 调用,上下文的队列所有者是主线程。 performBlock: 调用也是在主线程上进行的,所以我不明白为什么会出现此错误。我是不是遗漏了什么或者是 iOS 8 中的错误?

最佳答案

调用 -[NSManagedObjectContext init] 只是 -[NSManagedObjectContext initWithConcurrencyType:] 的包装,参数为 NSConfinementConcurrencyType。这将创建一个 NSManagedObjectContext 实例,该实例使用过时的线程限制模型 - 使用队列。使用 initinitWithConcurrencyType: 传递的值 NSConfinementConcurrencyType 创建的上下文与队列方法 performBlock: 不兼容或执行 block 和等待:

使用 -[NSManagedObjectContext initWithConcurrencyType:] 创建上下文,并根据需要传递 NSPrivateQueueConcurrencyTypeNSMainQueueConcurrencyType。作为结果创建的上下文performBlock:performBlockAndWait: 兼容,并将使用 iOS 5 中引入的队列限制模型.

关于objective-c - NSManagedObjectContext 和 performBlock,iOS 8 上的变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26846260/

相关文章:

objective-c - 提供回调函数作为特定的指针类型

ios - NSString 表情符号文字

ios - CoreData - 安全检查 CoreData 对象的值

ios - 每秒保存到核心数据性能

ios - iOS 13 Core Data 持久化存储迁移过程中出现错误

ios/xcode/核心数据 : How to refresh detail view in Master Detail setup

ios - iPhone - 如何将 .caf 音频文件转换为 .aac?

objective-c - ObjC 方法声明之前的 + 和 - 符号有正式名称吗?

ios - 如何在 Swift 中使用 UIDatePicker 仅在没有日期组件的情况下将时间存储在 CoreData 中?

ios - 如何在 iOS 的 HealthKit 中保存 HKQuantityTypeIdentifierBodyMass 类型的样本