CoreData - 如何使对象在不同的线程/上下文中保持最新?
Posted
技术标签:
【中文标题】CoreData - 如何使对象在不同的线程/上下文中保持最新?【英文标题】:CoreData - how to keep the object up-to-date in a different thread/context? 【发布时间】:2014-08-30 06:47:55 【问题描述】:我的应用程序有 2 个ManagedObject
s:Article
和 List
。它们之间存在多对多关系(一篇文章可以在多个列表中;该列表可以包含多篇文章)。
在文章的 UI 中,我有一个 +
按钮,它显示(在弹出框控制器中)Lists
的列表,并允许从其中添加或删除文章。
所以在ArticleViewController
中,我将Article 对象的一个实例作为属性:self.article
。
ListsTableViewController *contentViewController = [[ListsTableViewController alloc] initWithStyle:UITableViewStylePlain];
contentViewController.selectionBlock = ^(BOOL wasSelected, List *list)
NSLog(@"%@ was%@ selected?", list, wasSelected ? @"" : @" not");
if (wasSelected)
[self.article addToList:list];
else
[self.article removeFromList:list];
;
self.myPopoverController = [[WEPopoverController alloc] initWithContentViewController:contentViewController];
contentViewController.selectedLists = [NSMutableArray arrayWithArray:[[self.article.lists allObjects] valueForKeyPath:@"objectID.URIRepresentation"]];
[contentViewController viewDidAppear:YES];
[self.myPopoverController presentPopoverFromBarButtonItem:sender
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
我将列表中的objectID.URIRepresentation
s 的列表传递给contentViewController
,它允许我最初在最初选择的列表上显示复选标记。
Article
对象的addToList:
和removeFromList:
方法如下所示(我在我的项目中使用MagicalRecord
):
- (void) addToList:(List *)list
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext)
List *l = [list MR_inContext:localContext];
Article *n = [self MR_inContext:localContext];
NSMutableSet *s = [NSMutableSet setWithSet:n.lists];
[s addObject:l];
n.lists = s;
s = [NSMutableSet setWithSet:l.articles];
[s addObject:n];
l.articles = s;
completion:nil
];
当我第一次输入ArticleViewController
并点击+
按钮时,它会正确显示文章所在的列表。但是,当我从那里的列表中添加/删除时,请关闭弹出视图控制器并打开再说一遍,self.article
似乎没有设置更新的列表(它们似乎被添加到不同的线程/上下文中并且没有传播到这个?)。我第一次看到那里的清单。
退出ArticleViewController
并返回解决了问题(强制重新读取),但在第一次添加后问题仍然存在。
如何使Article
中设置的Lists
在被访问时强制重新获取关系?
【问题讨论】:
你为什么要NSMutableSet *s = [NSMutableSet setWithSet:n.lists];
?你为什么不使用 KVC 访问器来处理关系?
【参考方案1】:
经过几个小时的反复试验,我找到了一个可行的解决方案(至少目前可行)。我不确定它有多智能:
- (void) addToList:(List *)list
__block NSSet *set;
NSManagedObjectContext *c = self.managedObjectContext;
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext)
List *l = [list MR_inContext:localContext];
Article *n = [self MR_inContext:localContext];
NSMutableSet *s = [NSMutableSet setWithSet:n.lists];
[s addObject:l];
n.lists = s;
set = n.lists;
completion:^(BOOL success, NSError *error)
NSMutableSet *set2 = [NSMutableSet set];
for (List *l in [set allObjects])
[set2 addObject:[l MR_inContext:c]];
self.lists = set2;
];
- (void) removeFromList:(List *)list
__block NSSet *set;
NSManagedObjectContext *c = self.managedObjectContext;
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext)
List *l = [list MR_inContext:localContext];
Article *n = [self MR_inContext:localContext];
NSMutableSet *s = [NSMutableSet setWithSet:n.lists];
[s removeObject:l];
n.lists = s;
set = n.lists;
completion:^(BOOL success, NSError *error)
NSMutableSet *set2 = [NSMutableSet set];
for (List *l in [set allObjects])
[set2 addObject:[l MR_inContext:c]];
self.lists = set2;
];
【讨论】:
以上是关于CoreData - 如何使对象在不同的线程/上下文中保持最新?的主要内容,如果未能解决你的问题,请参考以下文章