【发布时间】:2015-08-25 14:37:18
【问题描述】:
我有一个应用程序,我在启动时使用操作列表下载数据,但由于未知的核心数据原因,它随机崩溃,所以我花了几天时间检查使用 MagicalRecord 在多线程核心数据中更新/获取数据的最佳实践。其中一个选项是启用多线程调试器-com.apple.CoreData.ConcurrencyDebug 1,当 Xcode 违反其中一项规则时,它会停止应用程序。所以,Xcode 在这条线上停止了我的应用程序[SyncRequestEntity MR_createEntityInContext:[self getPrivateContext]]
+ (MagicalRecordVersionNumber) version
{
return MagicalRecordVersionNumber2_3;
}
@implementation NSManagedObjectContext (MagicalRecord)
+ (NSManagedObjectContext *) MR_context
{
return [self MR_contextWithParent:[self MR_rootSavingContext]];
}
+ (NSManagedObjectContext *) MR_contextWithParent:(NSManagedObjectContext *)parentContext
{
NSManagedObjectContext *context = [self MR_newPrivateQueueContext];
[context setParentContext:parentContext];
[context MR_obtainPermanentIDsBeforeSaving];
return context;
}
- (void) MR_obtainPermanentIDsBeforeSaving
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(MR_contextWillSave:)
name:NSManagedObjectContextWillSaveNotification
object:self];
}
+ (NSManagedObjectContext *) MR_newPrivateQueueContext
{
NSManagedObjectContext *context = [[self alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
MRLogInfo(@"Created new private queue context: %@", context);
return context;
}
@end
@implementation MyClass
- (NSManagedObjectContext *) getPrivateContext
{
if (self.privateContext == nil)
{
self.privateContext = [NSManagedObjectContext MR_context];
}
return self.privateContext;
}
- (SyncRequestEntity *) getSyncRequest
{
SyncRequestEntity *syncRequest = [SyncRequestEntity MR_findFirstByAttribute:@"key" withValue:self.itemKey inContext:[self getPrivateContext]];
// Checking if the entity was sync previously with the same filters.
if (syncRequest == nil)
{
syncRequest = [SyncRequestEntity MR_createEntityInContext: [self getPrivateContext]];
}
return syncRequest;
}
@end
@implementation NSManagedObject (MagicalRecord)
+ (id) MR_createEntityInContext:(NSManagedObjectContext *)context
{
if ([self respondsToSelector:@selector(insertInManagedObjectContext:)] && context != nil)
{
id entity = [self performSelector:@selector(insertInManagedObjectContext:) withObject:context];
return entity;
}
else
{
NSEntityDescription *entity = nil;
if (context == nil)
{
entity = [self MR_entityDescription];
}
else
{
entity = [self MR_entityDescriptionInContext:context];
}
if (entity == nil)
{
return nil;
}
return [[self alloc] initWithEntity:entity insertIntoManagedObjectContext:context];
}
}
@end
privateContext 是每个操作的局部变量,因此我对每个操作都有私有上下文,以免中断主要操作。关键是我为每个线程创建了一个私有上下文,我只是试图使用这个上下文创建一个新的NSManagedObject 实例,Xcode 说我违反了多线程核心数据规则。有没有人知道发生了什么?
【问题讨论】:
-
MR_context的代码是什么?您是否考虑到块可以在不同的线程上运行? -
添加细节@AminNegm-Awad。我这里没有使用任何块。
-
您使用的是哪个版本的 MagicalRecord?
-
@casademora,你可以在上面更新的代码中看到它是 2.3。
标签: ios multithreading core-data magicalrecord