gpt4 book ai didi

ios - CoreData 和线程安全

转载 作者:可可西里 更新时间:2023-11-01 06:23:14 25 4
gpt4 key购买 nike

我有一个单例名称 CoreDataManager,它在其中注册了 mergeContextChangesForNotification:

+ (id) sharedManager{
static CoreDataManager *mSharedManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
mSharedManager = [[CoreDataManager alloc] init];
});
return mSharedManager;
}

- (id)init
{
self = [super init];
if (self) {
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(mergeContextChangesForNotification:)
name:NSManagedObjectContextDidSaveNotification
object:nil];
});
}
return self;
}

收到通知后:

- (void)mergeContextChangesForNotification:(NSNotification *)notification {
[shareContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:)
withObject:notification
waitUntilDone:YES];
}

我有两个问题:

  1. 我应该在这里使用 performSelectorOnMainThread 吗?自 this answer说从不。我应该将其更改为 GCD 并使用 dispatch_get_main_queue 吗??
  2. init 中注册 mergeContextChangesForNotification 是否是确保通知始终在主线程中注册的好做法?我从this answer读到的

最佳答案

对于 iOS 5/OS X 10.7 中引入的托管对象并发类型,它是首选使用 performBlock 方法来确保核心数据操作被执行在正确的线程上(更准确地说:在正确的队列上)。

所以你会创建共享上下文

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

并将来自其他上下文的更改合并

- (void)mergeContextChangesForNotification:(NSNotification *)notification {
[shareContext performBlock:^{
[shareContext mergeChangesFromContextDidSaveNotification:notification];
}];
}

另请注意(如 NSManagedObjectContext 文档中所述),它是建议仅注册来自已知上下文的保存通知。在您的注册中使用 object:nil,您可能会收到意想不到的通知,因为系统框架在内部使用核心数据。

因此,您应该只为您创建的上下文注册。或者,您可以检查通知是从具有相同持久存储协调器的上下文发送的:

- (void)mergeContextChangesForNotification:(NSNotification *)notification {
NSManagedObjectContext *otherContext = [notification object];
if (otherContext != shareContext &&
[otherContext persistentStoreCoordinator] == [shareContext persistentStoreCoordinator]) {
[shareContext performBlock:^{
[shareContext mergeChangesFromContextDidSaveNotification:notification];
}];
}
}

最后,通知方法总是在它发布的线程上被调用。在哪个线程上注册 通知并不重要。所以不需要将注册分派(dispatch)到主线程。

关于ios - CoreData 和线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20898772/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com