Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/112.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios CoreData&x2B;多线程模式。我做得对吗?_Ios_Objective C_Design Patterns_Core Data - Fatal编程技术网

Ios CoreData&x2B;多线程模式。我做得对吗?

Ios CoreData&x2B;多线程模式。我做得对吗?,ios,objective-c,design-patterns,core-data,Ios,Objective C,Design Patterns,Core Data,我编写了一个iOS应用程序,它使用核心数据来存储其内容。数据存储在托管对象中,并在单独的线程中更新(我使用GCD)。苹果公司在其核心数据编程指南中提出了两种方式来采用多线程环境中使用的核心数据: 为每个线程创建一个单独的托管对象上下文,并共享一个持久存储协调器。 这是典型的推荐方法 为每个线程创建单独的托管对象上下文和持久存储协调器。 这种方法提供了更高的并发性,但代价是更高的复杂性(特别是当您需要在不同上下文之间传递更改时)和更高的内存使用率 所以我选择了第一个。 我有一个数据库类,它管理所有

我编写了一个iOS应用程序,它使用核心数据来存储其内容。数据存储在托管对象中,并在单独的线程中更新(我使用GCD)。苹果公司在其
核心数据编程指南
中提出了两种方式来采用多线程环境中使用的核心数据:

  • 为每个线程创建一个单独的托管对象上下文,并共享一个持久存储协调器。 这是典型的推荐方法
  • 为每个线程创建单独的托管对象上下文和持久存储协调器。 这种方法提供了更高的并发性,但代价是更高的复杂性(特别是当您需要在不同上下文之间传递更改时)和更高的内存使用率
  • 所以我选择了第一个。 我有一个
    数据库
    类,它管理所有与核心数据相关的东西

    //Database.h
    #进口
    @接口数据库:NSObject
    @属性(非原子、保留、只读)NSManagedObjectModel*模型;
    @属性(非原子、保留、只读)NSManagedObjectContext*上下文;
    @属性(非原子、保留、只读)NSPersistentStoreCoordinator*coordinator;
    +(数据库*)共享状态;
    @结束
    //数据库.m
    #导入“Database.h”
    静态NSManagedObjectModel*sharedModel;
    静态NSPersistentStoreCoordinator*sharedCoordinator;
    静态NSMutableDictionary*上下文;
    @实现数据库
    +(NSMutableDictionary*)上下文字典
    {
    如果(!上下文){
    context=[[NSMutableDictionary alloc]init];
    }
    返回上下文;
    }
    +(NSManagedObjectContext*)contextForThread:(NSThread*)线程
    {
    id threadKey=@(thread.hash);
    NSManagedObjectContext*上下文=[Database contextsDictionary][threadKey];
    如果(!上下文){
    context=[[NSManagedObjectContext alloc]init];
    context.persistentstorecordinator=sharedCoordinator;
    上下文[线程键]=上下文;
    [上下文释放];
    [[NSNotificationCenter defaultCenter]添加观察者:[数据库类]
    选择器:@selector(threadWillExit:)
    名称:NSThreadWillExitNotification
    对象:线程];
    }
    返回上下文;
    }
    +(无效)线程将退出:(NSThread*)线程
    {
    id threadKey=@(thread.hash);
    [contexts removeObjectForKey:threadKey];
    [[NSNotificationCenter defaultCenter]removeObserver:[数据库类]
    名称:NSThreadWillExitNotification
    对象:线程];
    }
    +(数据库*)共享状态
    {
    静态数据库*共享;
    静态调度一次;
    一次发送(一次发送)^{
    shared=[[Database alloc]init];
    });
    收益共享;
    }
    -(id)init
    {
    self=[super init];
    如果(自我){
    sharedModel=[[NSManagedObjectModel mergedModelFromBundles:nil]retain];
    sharedCoordinator=[[NSPersistentStoreCoordinator alloc]initWithManagedObjectModel:sharedModel];
    NSString*docsDir=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES)lastObject];
    NSURL*storeUrl=[NSURL fileURLWithPath:[docsDir stringByAppendingPathComponent:@“MyModelFile”];
    n错误*错误=nil;
    [sharedCoordinator addPersistentStoreWithType:NSBinaryStoreType
    配置:无
    URL:storeUrl
    选项:无
    错误:&错误];
    NSAssert(!error,@“初始化错误%@”,error);
    }
    回归自我;
    }
    -(NSManagedObjectModel*)模型
    {
    返回共享模型;
    }
    -(NSPersistentStoreCoordinator*)协调员
    {
    返回共享协调员;
    }
    -(NSManagedObjectContext*)上下文
    {
    返回[Database contextForThread:[NSThread currentThread]];
    }
    -(无效)解除锁定
    {
    [[NSNotificationCenter defaultCenter]移除观察者:self];
    [共享模型发布];
    [共享协调员发布];
    [背景发布];
    [super dealoc];
    }
    @结束
    
    所以我很好奇,我做对了吗?我的代码有什么问题吗?这里有我可以使用的模式吗


    谢谢。

    所描述的多线程模式现在不相关,因为核心数据具有内置并发支持。如文章中所述,moc可以配置适当的并发类型
    NSPrivateQueueConcurrencyType
    NSMainQueueConcurrencyType
    。然后,可以在传递给
    performBlock
    performBlock和wait
    方法的块中执行托管对象上下文的每个操作,并让核心数据内部处理所有并发内容。

    请查看。使用新并发类型NSMainQueueConcurrencyType和NSPrivateQueueConcurrencyType的托管对象上下文会自动管理它们的队列(和线程),并且使用起来更方便。不幸的是,“核心数据编程指南”中还没有提到这一点。这是一篇关于核心数据和并发性的伟大文章:好吧,你们两位建议的文章真的很有帮助,现在所有的事情都可以做得更简单了!谢谢