我有一个由NSFetchedResultsController管理的表视图。但是,我遇到了查找或创建操作的问题。当用户点击表格视图的底部时,我正在查询我的服务器以获取另一批内容。如果它不存在于本地缓存中,我们创建它并存储它。但是,如果确实存在,我想将该数据附加到获取的结果控制器并显示它。我不太清楚这一部分。
这是我到目前为止所做的事情:
setFetchLimit:
)。即使有1000行,我也只想要100个可访问的行。在合并期间,将步骤4中新创建的对象插入到表中,但任何已存在且刚刚获取的对象都不会。这是我的NSOperation的相关代码
for (NSDictionary *resultsDict in self.results)
{
NSNumber *dbID = [NSNumber numberWithLong:[[resultsDict valueForKey:@"id"] longValue]];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:kResultEntityName inManagedObjectContext:moc]];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat: @"(dbID == %@)", dbID]];
NSError *error = nil;
NSManagedObject *newObject = nil;
// Query the data store to see if the object exists
newObject = [[moc executeFetchRequest:fetchRequest error:&error] lastObject];
[fetchRequest release];
// If it doesn't exist, create it.
if ((tweet == nil))
{
// Create the NSManagedObject and insert it into the MOC.
}
}
我想传递给主线程的是新创建的对象以及每次循环迭代时可能在获取请求中获取的任何现有对象。
我觉得这很简单,我很想念,并且可以在正确的方向上轻推。
答案 0 :(得分:1)
此时,之前未在我的Core Data存储中本地缓存的任何对象都会出现,但之前存在的对象不会出现。
你能解释一下吗?我不确定你以前存在的是什么意思。它是否与您现在在检索后执行的表上的过滤器不匹配,或者您是说先前的对象从表中消失了?
另外,您如何实现NSFetchedResultsController
的委托方法?您是在进行简单的表重新加载还是插入/移动行?
有几种方法可以做到这一点,但他们需要您进行一些实验。我首先想要“触摸”所取出的物体。也许更新'lastAccessed'日期或某些东西,以便这些对象将合并为“更新”。我怀疑这是最简单的方法。
Baring,另一个选择是将这些对象的通知广播回主线程(使用他们的NSManagedObjectID
作为跨越线程边界的载体),以便您可以手动更新它们;但这不太理想。
答案 1 :(得分:0)
嘿贾斯汀,你的fetchLimit
可能造成这种情况吗?
NSFetchedRequestController
时 初始化查询最新的100 数据库的结果(使用setFetchLimit:
)。即使有 1000行,我只想要100个可访问 起初。
无论您插入了多少个管理对象,NSFetchedResultsController
仍然会有100个结果的限制。合并。
您是否打开了排序?如果是这样,一些插入的托管对象可能会显示,因为它们取代了现有的100个,这是由于结果的排序。
我在获取结果的“页面”方面遇到了同样的问题,并且在我的提取中使用了下限约束(使用NSComparisonPredicate
中的sorted属性)并使用最后一项进行调整在最近的“页面”结果中。
我也尝试了fetchLimit方法,这也有效。你不需要删除&重建NSFetchedResultsController
,你可以调整fetchRequest的fetchLimit:
tableMaxItems += 100;
[myFRC.fetchRequest setFetchLimit:tableMaxItems];
答案 2 :(得分:0)
以下是我最终解决这个问题的方法。在合并来自NSOperation
的MOC的更改之前,我遍历NSUpdatedObjectsKey
中存储的值并使用willAccessValueForKey触摸它们。为了让他们进入NSUpdatedObjects
密钥,我上面提到了Marcus的建议并添加了一个lastAccessed属性,如果该对象已存在于持久存储中,我将其设置为NSOperation
中的当前日期。
- (void)mergeChanges:(NSNotification *)notification
{
NSAssert([NSThread mainThread], @"Not on the main thread");
NSSet *updatedObjects = [[notification userInfo] objectForKey:NSUpdatedObjectsKey];
for (NSManagedObject *object in updatedObjects)
{
[[managedObjectContext objectWithID:[object objectID]] willAccessValueForKey:nil];
}
[managedObjectContext mergeChangesFromContextDidSaveNotification:notification];
}