2015-08-25 137 views
1

我有一個應用程序,我在啓動時使用操作列表下載數據,並且隨機因未知核心數據原因崩潰,因此我花了幾天的時間檢查最佳實踐,以更新/獲取多線程內核中的數據數據與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我的應用程序是一個局部變量爲每個操作,所以我有私人上下文的每一個操作,以不中斷主之一。重點是我爲每個線程創建一個私有上下文,我只是試圖使用這個上下文創建一個新的實例,並且Xcode說我違反了多線程核心數據規則。有沒有人對發生的事情有任何線索?

+0

什麼碼'MR_context'的?你有沒有考慮到塊可以在不同的線程上運行? –

+0

添加詳情@ AminNegm-Awad。我在這裏沒有使用任何塊。 – Maystro

+0

您正在使用哪個版本的MagicalRecord? – casademora

回答

0

我們在開發自己的應用程序時遇到同樣的問題。

當您嘗試在與上下文不同的線程中執行寫操作時,它有時會崩潰。

我們的解決方案是在AppDelegate.m文件上創建一個私人經理。只需添加以下代碼:

- (NSManagedObjectContext *)getPrivateManagedObjectContext 
{ 
    if (self.managedObjectContext != nil) { 
     return self.managedObjectContext; 
    } 

    NSPersistentStoreCoordinator *coordinator = [self getPersistentStoreCoordinator]; 
    if (coordinator != nil) { 
     self.managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
     [self.managedObjectContext setPersistentStoreCoordinator:coordinator]; 
    } 
    return self.managedObjectContext; 
} 

然後,當你需要執行任何操作,你應該使用這種方法,以確保該塊的上下文的同一個線程上運行:

[self.managedObjectContext performBlock:^{...}]; 
[self.managedObjectContext performBlockAndWait:^{...}]; 
+0

爲什麼我需要使用performBlock?我已經在一個後臺線程(NSOperation)我只想創建/獲取/插入實體使用我爲每個操作創建的privateContext,但它似乎違反了我迄今爲止不了解的規則之一。 – Maystro

+0

此解決方案未使用MagicalRecord ... – casademora

+0

問題是如果您執行同時寫入操作,它可能會崩潰。您只需使用一個私有上下文並在同一個上下文線程中執行每個操作。 –