我正在将一些代码从我的控制器移到核心数据应用程序中的模型中。
我编写了一种方法,该方法针对我定期发出的特定提取请求返回NSManagedObjectID。
+ (NSManagedObjectID*)teamProjectWithProjectId:(NSNumber *)projectId inContext:(NSManagedObjectContext*)context
{
NSFetchRequest *teamRequest = [[NSFetchRequest alloc] initWithEntityName:@"TeamProject"];
NSPredicate *teamPredicate = [NSPredicate predicateWithFormat:@"teamProjectId == %@",projectId];
teamRequest.predicate = teamPredicate;
TeamProject *teamProject = [[context executeFetchRequest:teamRequest error:nil] lastObject];
if (teamProject)
{
return [teamProject objectID];
}
else
{
return nil;
}
return nil;
}
现在到处都需要使用执行此操作的方法:
NSManagedObjectID *teamProjectMoId = [TeamProject teamProjectWithProjectId:projectID];
TeamProject *currentProject = nil;
if (teamProjectMoId)
{
currentProject = (TeamProject*)[self.managedObjectContext objectWithID:teamProjectMoId];
}
现在,这还算不错,它可以正常工作,并且尊重NSManagedObject不是线程安全的,而NSManagedObjectID是线程安全的。我很高兴能够将很多代码从控制器类中移出到模型类别中。
但是,这还不够好。我真的想以尊重线程安全的方式仅用一行代码访问NSManagedObject。我的理想是能够写这样的东西:
TeamProject *currentProject = [TeamProject magicalMethodThatHandlesThreadSafety];
这有可能吗?还是没有人有任何策略为NSManagedObject编写干净的访问器方法?
最佳答案
您可以在需要在后台进行查找的任何地方创建一个临时MOC。这肯定是线程安全的,并且比使用ID更快(实际上,这是快速的,因为创建自身的MOC速度很快)。
一种实现方式是通过子级在您的主上下文中指定NSPrivateQueueConcurrencyType
并发类型:
+ (TeamProject*)teamProjectWithProjectId:(NSNumber *)projectId inContext:(NSManagedObjectContext*)context
{
NSManagedObjectContext *temporaryContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
temporaryContext.parentContext = context;
NSFetchRequest *teamRequest = [[NSFetchRequest alloc] initWithEntityName:@"TeamProject"];
NSPredicate *teamPredicate = [NSPredicate predicateWithFormat:@"teamProjectId == %@",projectId];
teamRequest.predicate = teamPredicate;
TeamProject *teamProject = [[temporaryContext executeFetchRequest:teamRequest error:nil] lastObject];
return teamProject;
}
还可以查看this post以获得更多方案和解决方案。
编辑:
为了使情况更清楚,上述方法应从使用返回的MO的同一线程中调用。这只是上述方法的“扩展”,因为它使用本地创建的MOC(该线程专用)包装了提取操作,因此您可以安全地使用它。
换句话说,您可以从任何线程调用上述方法,并在同一线程中安全地使用返回的MO。使用子MOC的技巧使您可以通过创建临时私有MOC在任何线程中进行访存。
可以安全地引用在另一个线程中创建的MOC,以在当前线程中创建子MOC。
仍然确实不允许将托管对象从一个线程传递到另一个线程。
关于ios - 传递NSManagedObject,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19187584/