Rui*_*pes 40 iphone multithreading core-data grand-central-dispatch ios
我是Grand Central Dispatch(GCD)和Core Data的初学者,我需要你的帮助来使用带有CGD的Core Data,这样当我向Core Data添加40.000条记录时,UI不会被锁定.
我知道CD不是线程安全的,所以我必须使用另一个上下文,然后保存数据和合并上下文,就我从一些文章中能够理解的那样.
我还做不到的是把各个部分放在一起.
所以,在我的代码中,我需要你的帮助,如何做到这一点.
我有:
/*some other code*/
for (NSDictionary *memberData in arrayWithResult) {
//get the Activities for this member
NSArray *arrayWithMemberActivities = [activitiesDict objectForKey:[memberData objectForKey:@"MemberID"]];
//create the Member, with the NSSet of Activities
[Members createMemberWithDataFromServer:memberData
andActivitiesArray:arrayWithMemberActivities
andStaffArray:nil
andContactsArray:nil
inManagedObjectContext:self.managedObjectContext];
}
Run Code Online (Sandbox Code Playgroud)
如何将其转换为在后台工作,然后,在完成保存后,保存数据并更新UI,而不会在保存40.000对象时阻止UI?
Rog*_*Rog 57
这是您尝试的一个很好的例子.如果您有任何疑问,请随时回来:
self.mainThreadContext... // This is a reference to your main thread context
NSPersistentStoreCoordinator *mainThreadContextStoreCoordinator = [self.mainThreadContext persistentStoreCoordinator];
dispatch_queue_t request_queue = dispatch_queue_create("com.yourapp.DescriptionOfMethod", NULL);
dispatch_async(request_queue, ^{
// Create a new managed object context
// Set its persistent store coordinator
NSManagedObjectContext *newMoc = [[NSManagedObjectContext alloc] init];
[newMoc setPersistentStoreCoordinator:mainThreadContextStoreCoordinator]];
// Register for context save changes notification
NSNotificationCenter *notify = [NSNotificationCenter defaultCenter];
[notify addObserver:self
selector:@selector(mergeChanges:)
name:NSManagedObjectContextDidSaveNotification
object:newMoc];
// Do the work
// Your method here
// Call save on context (this will send a save notification and call the method below)
BOOL success = [newMoc save:&error];
if (!success)
// Deal with error
[newMoc release];
});
dispatch_release(request_queue);
Run Code Online (Sandbox Code Playgroud)
并响应上下文保存通知:
- (void)mergeChanges:(NSNotification*)notification
{
dispatch_async(dispatch_get_main_queue(), ^{
[self.mainThreadContext mergeChangesFromContextDidSaveNotification:notification waitUntilDone:YES];
});
}
Run Code Online (Sandbox Code Playgroud)
完成后台线程上下文后,不要忘记从通知中心删除观察者.
[[NSNotificationCenter defaultCenter] removeObserver:self];
Run Code Online (Sandbox Code Playgroud)
这是一个以最简单的术语涵盖GCD和UI的片段.您可以将doWork替换为执行CoreData工作的代码.
关于CD和线程的安全性,关于GCD的一个很好的部分是,您可以对应用程序的各个区域(子系统)进行分区以进行同步并确保它们在同一队列上执行.您可以在名为com.yourcompany.appname.dataaccess的队列上执行所有CoreData工作.
在示例中,有一个按钮调用长时间运行的工作,一个状态标签,我添加了一个滑块,以显示我可以在bg工作完成时移动滑块.
// on click of button
- (IBAction)doWork:(id)sender
{
[[self feedbackLabel] setText:@"Working ..."];
[[self doWorkButton] setEnabled:NO];
// async queue for bg work
// main queue for updating ui on main thread
dispatch_queue_t queue = dispatch_queue_create("com.sample", 0);
dispatch_queue_t main = dispatch_get_main_queue();
// do the long running work in bg async queue
// within that, call to update UI on main thread.
dispatch_async(queue,
^{
[self performLongRunningWork];
dispatch_async(main, ^{ [self workDone]; });
});
// release queues created.
dispatch_release(queue);
}
- (void)performLongRunningWork
{
// simulate 5 seconds of work
// I added a slider to the form - I can slide it back and forth during the 5 sec.
sleep(5);
}
- (void)workDone
{
[[self feedbackLabel] setText:@"Done ..."];
[[self doWorkButton] setEnabled:YES];
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14051 次 |
| 最近记录: |