仍在致力于将应用程序从每次使用或显示信息时下载信息,转变为使用 CoreData 将其缓存在手机上(由 MagicalRecord 提供)。这是在 iOS 7 上
因为我们没有设置数据推送系统来在后端的某些数据发生变化时自动更新手机的缓存数据,所以在过去的几个月里(当我们致力于应用程序的其他方面时)我一直在思考如何管理在手机上保留数据的本地副本,并能够在缓存中保留最新的数据。
我意识到,只要我仍然每次都获取数据:-(我就可以使用手机的 CoreData 支持的数据缓存来显示和使用,并且只需使用数据的获取来更新手机上的数据库。
因此,我一直在将主要数据对象从构成完整对象的下载数据转换为这些主要数据对象作为 CoreData 对象的轻型替代对象。
基本上,应用程序中的每个普通数据对象并不在内部包含该对象的所有属性,而是仅包含底层 CoreData 对象的 objectID,也可能在内部包含应用程序特定的 ID,所有其他属性都是动态的并从 CoreData 获取对象并传递(大多数属性是只读的,更新是通过批量重写 JSON 中传递的核心数据来完成的)
像这样:
- (NSString *)amount
{
__block NSString *result = nil;
NSManagedObjectContext *localContext = [NSManagedObjectContext MR_newContext];
[localContext performBlockAndWait:^{
FinTransaction *transaction = (FinTransaction *)[localContext existingObjectWithID:[self objectID] error:nil];
if (nil != transaction)
{
result = [transaction.amount stringValue];
}
}];
return result;
}
有时需要设置一个,如下所示:
- (void)setStatus:(MyTransactionStatus)status
{
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
FinTransaction *transaction = (FinTransaction *)[localContext existingObjectWithID:[self objectID] error:nil];
if (nil != transaction)
{
transaction.statusValue = status;
}
} completion:^(BOOL success, NSError *error){}];
}
现在,我的问题是我有一个视图控制器,它基本上使用 NSFetchedResultsController 在表视图中显示本地手机 CoreData 数据库中存储的数据。在发生这种情况的同时,用户可能开始滚动数据,手机会启动一个线程来下载数据更新,然后开始使用更新后的数据更新 CoreData 数据存储,此时它会在主线程上运行异步 GCD 回调,让获取的结果控制器重新获取其数据,并告诉表视图重新加载。
问题是,如果用户滚动初始获取结果控制器获取的数据和表视图加载,并且后台线程正在后台更新相同的 Core Data 对象,则会发生死锁。获取和重写的实体并不完全相同(当发生死锁时),即,不是读取和写入对象 ID 1,而是使用相同的持久数据存储。
每次访问(读或写)都发生在MR_saveWithBlock
or MR_saveWithBlockAndWait
(写入/更新数据)视情况而定,并且 [localContext PerformBlock:] 或 [localContext PerformBlockAndWait:] 可能合适。每个单独的读或写都有自己的NSManagedObjectContext
。我没有看到任何地方有任何挂起的杂散挂起的更改,并且它阻塞和死锁的实际位置并不总是相同的,但总是与主线程从与后台线程所使用的相同的持久存储中读取数据有关。更新数据。
获取结果控制器的创建如下:
_frController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:[NSManagedObjectContext MR_rootSavingContext]
sectionNameKeyPath:sectionKeyPath
cacheName:nil];
然后一个performFetch
已经完成了。
当我需要在表视图中显示范围数据并使用新数据在后台更新数据存储时,如何最好地构建此类操作?
当我使用时MagicalRecord
对于其中的大部分内容,无论是否使用 MagicalRecord(直接 CD),我都愿意接受评论、答案等。