加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ios – 为什么在尝试访问获取对象的属性时会出现CoreData多线程

发布时间:2020-12-14 19:42:29 所属栏目:百科 来源:网络整理
导读:以下代码适用于没有最后一个语句.但是,在最后一行,Xcode停止并显示以下消息: CoreData`+[NSManagedObjectContext Multithreading_Violation_AllThatIsLeftToUsIsHonor ]: NSManagedObjectContext *context = GLOBAL_appDelegate.coreDataHelper.contextBack
以下代码适用于没有最后一个语句.但是,在最后一行,Xcode停止并显示以下消息:

CoreData`+[NSManagedObjectContext
Multithreading_Violation_AllThatIsLeftToUsIsHonor]:

NSManagedObjectContext *context = GLOBAL_appDelegate.coreDataHelper.contextBackground;
    [context performBlock:^{
         NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
         [fetchRequest setEntity:[NSEntityDescription entityForName:@"CdTag" inManagedObjectContext:context]];
         NSPredicate *predicate = [NSPredicate predicateWithFormat:@"title BEGINSWITH[cd] %@",@"webpages"];
         [fetchRequest setPredicate:predicate];
         NSArray *cdTags = [context executeFetchRequest:fetchRequest error:nil];
         NSLog(@"number of tags: %li",cdTags.count);
         CdTag *cdTag = [cdTags objectAtIndex:0];

         // Accessing a property causes the assertion warning to be shown
         cdTag.title;
    }];

我正在使用Xcode 7 beta 5,我启用了多线程断言.

上下文定义如下:

_model = [NSManagedObjectModel mergedModelFromBundles:nil];
_coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:_model];
_context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[_context setPersistentStoreCoordinator:_coordinator];

_contextBackground = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_contextBackground setParentContext:_context];

这是一个Xcode错误还是我做错了什么?

解决方法

你还可以加上上下文初始化发生的代码吗?

您获得的错误与从初始化的线程/队列之外的线程/队列访问托管对象上下文有关.

通常发生的是使用默认/遗留“限制类型”并发类型初始化托管对象上下文

performBlock:

performBlockAndWait:

方法实际上不会做他们做广告的事情,即确保在初始化时与其关联的队列上访问上下文.

如果我上面提到的是实际发生的事情你可以(假设其他一切都已到位)通过初始化你的上下文来解决这个问题:

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

要么

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

这是关于并发策略的文档:

When you create a managed object context using initWithConcurrencyType:,you have three options for its thread (queue) association

Confinement (NSConfinementConcurrencyType)

For backwards compatibility,this is the default. You promise that context will not be used by any thread other than the one on which you created it. In general,to make the behavior explicit you’re encouraged to use one of the other types instead.

You can only use this concurrency type if the managed object context’s parent store is a persistent store coordinator.

Private queue (NSPrivateQueueConcurrencyType)

The context creates and manages a private queue.

Main queue (NSMainQueueConcurrencyType)

The context is associated with the main queue,and as such is tied into the application’s event loop,but it is otherwise similar to a private queue-based context. You use this queue type for contexts linked to controllers and UI objects that are required to be used only on the main thread.

If you use contexts using the confinement pattern,you send the contexts messages directly; it’s up to you to ensure that you send the messages from the right queue.

You use contexts using the queue-based concurrency types in conjunction with performBlock: and performBlockAndWait:.

Apple Docs

作为旁注,你得到的错误信息是仍然站在Cocoa内的最后几个“复活节彩蛋”之一.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读