CoreData 多线程传值的问题

来源:互联网 发布:windows sdk是什么 编辑:程序博客网 时间:2024/06/12 19:41
 CoreData中的NSManagedObjectContext在多线程中是不安全的,在多线程中使用CoreData时,你有可能会得到类似data: <fault>的错误信息,这本来是CoreData的一种懒加载机制,当你需要使用某条数据的时候,coredata才帮你加载对应的数据。但是用在多线程中的使用过程中,你可能加载不出对应的属性值,所以如果想要多线程访问CoreData的话,最好的方法是一个线程一个NSManagedObjectContext,这样在各个线程中对数据进行操作时,就能得到正确的数据。
虽然每个线程都重新创建一个NSManagedObjectContext可以解决问题,但是在项目中使用起来相对比较繁琐,代码量相对较多。并且在更新界面的时候,会面临在其他线程读取数据,然后去主线程更新界面的问题,这个时候整个操作过程就需要在至少两个线程中完成了。在线程传值过程中,就可能得不到正确的数据。
如下:
下面的代码是在使用了MagicalRecord框架的情况下的。如果对MagicalRecord不了解,可以访问github下载和学习,这篇博客上也有比较详细的讲解。

-(void)test  {

 [NSThread detachNewThreadSelector:@selector(loadLocalData) toTarget:self withObject:nil];

}

-(void) loadLocalData {

    NSArray *array = [Student MR_findAll];

self.array = [[NSArray alloc] initWithArray:array];

for (Student *stu in self.array) {

        NSLog(@"在 非主线程 中打印:Student:%@,name:%@",stu,stu.name);

    }

    [self performSelectorOnMainThread:@selector(readData:) withObject:self.array waitUntilDone:NO];

}

-(void)readData:(NSArray*) array {

    for (Student *stu in array) {

        NSLog(@"在主线程中打印:Student:%@,name:%@",stu,stu.name);

    }

}

你会发现上面的两次打印数据是不一样的。当然,你更改其中的一句代码就可以得到正确的结果

    [self performSelectorOnMainThread:@selector(readData:) withObject:self.array waitUntilDone:NO];

    [self performSelectorOnMainThread:@selector(readData:) withObject:self.array waitUntilDone:YES];

你只有让你当前的线程等待主线程执行完成之后再继续,你的查询才是有效地。
0 0
原创粉丝点击