Core Data iOS 8 Today Widget 问题
Posted
技术标签:
【中文标题】Core Data iOS 8 Today Widget 问题【英文标题】:Core Data iOS 8 Today Widget issue 【发布时间】:2014-09-18 23:49:00 【问题描述】:我有一个返回共享实例的 DataManager 类:
+ (DataManager *)sharedInstance;
static DataManager *sharedInstance = nil;
static dispatch_once_t pred;
dispatch_once(&pred, ^
sharedInstance = [[DataManager alloc] init];
);
return sharedInstance;
在这里我跟踪我的 managedObjectContext、managedObjectModel、persistentStoreCoordinator。
我还有一种方法可以取出项目进行展示:
- (NSArray *)getItems
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Item"];
return [[self managedObjectContext] executeFetchRequest:fetchRequest error:nil];
现在在我的主应用程序中,当我调用此 getItems 然后单独修改项目时,我有一个视图控制器。例如设置 item.itemName = @"testName";然后调用我的保存方法。
我还有一个 ios 8,在 TodayViewController 中我还调用了 getItems 方法。我有一个检测 managedObjectContext 保存的 NSNotification。
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refetchItems) name:NSManagedObjectContextDidSaveNotification object:[[DataManager sharedInstance] managedObjectContext]];
这些重新获取的项目确实会被调用,但会返回过时的 NSManagedObjects。因此,例如 itemName 没有更改为 @"testName"。
我哪里错了?如果您需要查看任何其他代码,请告诉我。
谢谢!
【问题讨论】:
您的应用和小部件在不同的进程中运行。如果您的应用更改了核心数据存储,您的小部件将不会收到应用发送的通知。 @quellish 那么检测变化的最佳方法是什么? 我也有同样的问题,但也没有找到解决办法。只有我能想到的,就是“破坏”上下文并重新创建它。 您确定您没有听到任何DidChange
通知吗?
@LeoNatan 我实际上听到了 DidChange 通知。只是重新获取不会让我得到更新的对象。奇怪的是,它确实检测到我添加的新对象或我删除了一些对象。
【参考方案1】:
您可以尝试以下方法来刷新特定的 ManagedObject。如果要刷新 ManagedObject 列表,则循环每个对象并执行命令。
[_managedObjectContext refreshObject:act mergeChanges:YES];
或者对于 iOS 8.3 及以上版本,您可以使用以下方法一次更新上下文中的所有 ManagedObject,如下所示。
[_managedObjectContext refreshAllObjects];
它有点作用,但只用于数据更新,不能用于添加或删除数据。
如果不工作,你也可以添加
[_managedObjectContext reset];
之后,您必须读取“重新分配”所有从核心数据存储中加载的变量。
另一种解决方案(更慢更丑)
如果上述方法不起作用,另一种解决方案是删除当前上下文并重新创建它。
我只是设置了
_persistentStoreCoordinator = nil;
_managedObjectModel = nil;
_managedObjectContext = nil;
我有具有此属性的 CoreDataManager 类
@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;
在课堂上,我手动创建了设置器。如果我将所有变量都归零,由于设置器,一旦我在核心数据管理器类之外读取它们,它们就会再次被初始化。
您可以通过使用NSUserDefault
商店来改善这一点。它正在正确更新。在主应用程序中,如果您更改某些内容,请在NSUserDefault
中设置标志。在扩展中,阅读此内容,如果标记了标志,则重置核心数据。这样,您将节省一些滴答声并加快速度。
对于NSUserDefault
的分配(在两个应用程序 - 扩展和主)使用这个 - 之后,您可以像往常一样从中读取数据并且它们应该是同步的
NSUserDefaults *prefs = [[NSUserDefaults alloc] initWithSuiteName:GROUP_NAME]; //share with extension
【讨论】:
以上是关于Core Data iOS 8 Today Widget 问题的主要内容,如果未能解决你的问题,请参考以下文章
将数据从 Core Data 加载到 Today Widget
UISearchController 和 UITableView 支持 Core Data iOS 8