我没有收到来自我给Simperium的NSManagedObjectContext的NSManagedObjectContextDidSaveNotification通知。
基本上,我喜欢做的是在数据库由于simperium更新而发生更新时通知我的应用程序。
因此,我使用2个NSManagedObjectContexts,一个用于我的应用程序,另一个用于Simperium。一旦我的应用程序保存了它的上下文,更改就会通过mergeChangesFromContextDidSaveNotification:合并到NSManagedObjectContextDidSaveNotification通知中的simperium上下文。
然而,问题是,每当对Simperium NSManagedObjectContext进行更新时,我都得不到NSManagedObjectContextDidSaveNotification,因此我无法将远程的更改合并到我的应用程序上下文中。我检查了它是否真的将数据保存到持久存储中。
下面是一些代码:
- (void) setSyncingEnabled:(BOOL)syncingEnabled
{
if (syncingEnabled && !self.simperium)
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(syncingObjectContextDidSaveNotification:)
name:NSManagedObjectContextDidSaveNotification
object:self.syncingObjectContext];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(objectContextDidSaveNotification:)
name:NSManagedObjectContextDidSaveNotification
object:self.objectContext];
self.simperium = [[Simperium alloc] initWithRootViewController:App.delegate.window.rootViewController];
self.simperium.authenticationOptional = YES;
[self.simperium addDelegate:self];
[self.simperium startWithAppID:kSimperiumAppId
APIKey:kSimperiumAPIKey
model:self.objectModel
context:self.syncingObjectContext
coordinator:self.storeCoordinator];
}
else if (self.simperium) {
self.simperium = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:self.syncingObjectContext];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:self.objectContext];
}
}
- (void) objectContextDidSaveNotification:(NSNotification*)notification
{
if (self.simperium) {
[self.syncingObjectContext mergeChangesFromContextDidSaveNotification:notification];
}
}
- (void) syncingObjectContextDidSaveNotification:(NSNotification*)notification
{
[self.objectContext mergeChangesFromContextDidSaveNotification:notification];
/* Inform Application */
[[NSNotificationCenter defaultCenter] postNotificationName:DatabaseDidUpdateExternallyNotification object:self];
}发布于 2012-08-15 03:43:25
由于您的目标是在更新发生时通过Simperium通知您的应用程序,因此有比使用单独的上下文( Simperium在内部执行)更好的选择:
1)您可以使用在插入、更改和删除对象时调用的NSFetchedResultsController。
2)您可以使用SimperiumDelegate来对特定的更改做出反应。这在目前正在GitHub上的"iosupdate“分支中测试的发行版中的工作方式略有不同。SPBucketDelegate将取代SimperiumDelegate协议,让您可以更好地控制您关心的通知。
如果由于某些原因你真的需要使用第二个上下文,请使用get in touch,这样我们就可以更多地讨论你的用例。
发布于 2012-08-16 03:18:29
我深入研究了一下,发现Simperium SDK使用的不是您提供的对象上下文,而是私下创建的另一个对象上下文。这就是为什么你给它的上下文永远不会被保存。目前还没有公共API来访问私有并发上下文。
如果你不想使用NSFetchedResultsController,因为你同步了很多对象,而且性能不是很好,你也可以在对象更新后发送一条通知来处理你的UI更新。
以下代码似乎可以工作(主分支):
-(void)objectKeysChanged:(NSSet *)keyArray entityName:(NSString *)entityName
{
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(informAppAboutExternalChange) object:nil];
[self performSelector:@selector(informAppAboutExternalChange) withObject:nil afterDelay:0.5];
}
- (void) informAppAboutExternalChange
{
[[NSNotificationCenter defaultCenter] postNotificationName:kObjectsDidChangeExternallyNotification object:nil];
}只需在需要更新UI的地方观察通知即可。延迟执行还应防止通知被频繁触发,这也会降低性能。
https://stackoverflow.com/questions/11955661
复制相似问题