我有一个单身名称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]; }
我有两个问题:
我应该performSelectorOnMainThread
在这里使用吗?因为这个答案说永远不会.我应该把它改成GCD并使用dispatch_get_main_queue
??
注册mergeContextChangesForNotification
in init
是否是一种很好的做法,以确保通知始终在主线程中注册?我从这个答案中读到了
Martin R.. 8
使用iOS 5/OS X 10.7中引入的托管对象并发类型,最好使用这些performBlock
方法来确保在正确的线程上执行Core Data操作(更确切地说:在正确的队列上).
所以你将创建共享上下文
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]; }]; } }
最后,始终在其发布的线程上调用通知方法.通知注册的线程无关紧要.因此,不需要将注册分派给主线程.
使用iOS 5/OS X 10.7中引入的托管对象并发类型,最好使用这些performBlock
方法来确保在正确的线程上执行Core Data操作(更确切地说:在正确的队列上).
所以你将创建共享上下文
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]; }]; } }
最后,始终在其发布的线程上调用通知方法.通知注册的线程无关紧要.因此,不需要将注册分派给主线程.