我一直在跟随CS193P斯坦福课程,特别是CoreData演讲/演示。在Paul Hegarty的Photomania应用程序中,他从表视图开始,并在后台填充数据,而不会对UI流程造成任何干扰。我创建了一个应用程序,列出本地区域的企业(来自返回JSON数据的API)。
我已经按照Paul的照片/摄影师类别创建了分类。类本身的创建不是问题,问题在于它们被创建的位置。
A simplified data structure:
- Section
- Sub-section
- business
- business
- business
- business
- business
- business
我的应用程序从一个UIViewController开始,其中包含几个按钮,每个按钮都打开对应部分的tableview(这些都很正常,我试图提供足够的信息,以便我的问题有意义)。 我调用一个辅助方法来创建/打开URL以用于UIManagedDocument,该文档基于这个问题。 这在应用程序运行时立即调用,并且加载速度快。
我有一个非常类似于Paul的fetchFlickrDataIntoDocument的方法:
-(void)refreshBusinessesInDocument:(UIManagedDocument *)document
{
dispatch_queue_t refreshBusinessQ = dispatch_queue_create("Refresh Business Listing", NULL);
dispatch_async(refreshBusinessQ, ^{
// Get latest business listing
myFunctions *myFunctions = [[myFunctions alloc] init];
NSArray *businesses = [myFunctions arrayOfBusinesses];
// Run IN document's thread
[document.managedObjectContext performBlock:^{
// Loop through new businesses and insert
for (NSDictionary *businessData in businesses) {
[Business businessWithJSONInfo:businessData inManageObjectContext:document.managedObjectContext];
}
// Explicitly save the document.
[document saveToURL:document.fileURL
forSaveOperation:UIDocumentSaveForOverwriting
completionHandler:^(BOOL success){
if (!success) {
NSLog(@"Document save failed");
}
}];
NSLog(@"Inserted Businesses");
}];
});
dispatch_release(refreshBusinessQ);
}
[myFunctions arrayOfBusinesses]只是解析JSON数据并返回一个包含各个业务的NSArray。
我在创建商家代码的开头和结尾处加入了NSLog。每个商家都被分配一个部分,需要0.006秒来创建,并且有数百个这样的商家。插入操作最终需要约2秒钟。
辅助方法如下:
// The following typedef has been defined in the .h file
// typedef void (^completion_block_t)(UIManagedDocument *document);
@implementation ManagedDocumentHelper
+(void)openDocument:(NSString *)documentName UsingBlock:(completion_block_t)completionBlock
{
// Get URL for document -> "<Documents directory>/<documentName>"
NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
url = [url URLByAppendingPathComponent:documentName];
// Attempt retrieval of existing document
UIManagedDocument *doc = [managedDocumentDictionary objectForKey:documentName];
// If no UIManagedDocument, create
if (!doc)
{
// Create with document at URL
doc = [[UIManagedDocument alloc] initWithFileURL:url];
// Save in managedDocumentDictionary
[managedDocumentDictionary setObject:doc forKey:documentName];
}
// If the document exists on disk
if ([[NSFileManager defaultManager] fileExistsAtPath:[url path]])
{
[doc openWithCompletionHandler:^(BOOL success)
{
// Run completion block
completionBlock(doc);
} ];
}
else
{
// Save temporary document to documents directory
[doc saveToURL:url
forSaveOperation:UIDocumentSaveForCreating
completionHandler:^(BOOL success)
{
// Run compeltion block
completionBlock(doc);
}];
}
}
在viewDidLoad中调用它:
if (!self.lgtbDatabase) {
[ManagedDocumentHelper openDocument:@"DefaultLGTBDatabase" UsingBlock:^(UIManagedDocument *document){
[self useDocument:document];
}];
}
useDocument函数只是将提供的文档设置为self.document。
我想要修改这段代码,使数据在另一个线程中插入,并且用户仍然可以点击按钮查看一个部分,而不会因为数据导入而卡住UI。
非常感谢您提供帮助。我已经花了几天时间研究这个问题,甚至在这里查找了其他类似的问题,但都没有解决。如果您需要其他信息,请告诉我!
谢谢。
编辑:
到目前为止,这个问题已经收到了一个反对票。如果有什么方法可以改进这个问题,或者有人知道我没有找到的问题,请评论说明如何或在哪里?如果您有其他原因投反对票,请让我知道,因为我不能理解这种消极情绪,而且很乐意学习如何更好地做出贡献。
[document updateChangeCount:UIDocumentChangeDone]
来强制保存。这是CS193P斯坦福课程中缺少的内容。 - Florian Mielke