2012-05-24 27 views
0

在玩具iOS項目中,我使用MagicalRecord在應用程序委託中設置CoreData堆棧。用下面的代碼:NSManagedObjectContext保存但不會持久

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    [MagicalRecord setupCoreDataStackWithStoreNamed:@"ToyProject.sqlite"]; 
    [[NSManagedObjectContext MR_defaultContext] setUndoManager:[[NSUndoManager alloc] init]]; 

... 
} 

我有NSManagedObject,我正在寫的一個子類(NSRailsManagedObject - 我分叉NSRails並增加CoreData的支持),我已經給了它一個saveContext方法:

- (void)saveContext { 
    dispatch_async(dispatch_get_main_queue(), ^{ 
    @try { 
     NSError *error = nil; 
     if (![self.managedObjectContext save:&error]) { 
      NSLog(@"Failed to save core data: %@", [error localizedDescription]); 
     } else { 
      NSLog(@"\"Successfully\" saved your data."); 
     } 
    } 
    @catch (NSException *exception) { 
     NSLog(@"Couldn't save your data! Try again later :("); 
    } 
    @finally { 
     NSLog(@"Look, I don't know what else to tell you, mang."); 
    } 
    }); 
} 

當我嘗試使用此方法保存此類的子類時,我收到無錯誤,並且保存表面上成功。但是,在應用程序的下一次運行中,上次運行中沒有任何數據存在。相反,如果saveContext方法包含下面的代碼,它的工作原理沒有問題:

- (void)saveContext { 
    [[NSManagedObjectContext MR_defaultContext] MR_save]; 
} 

而且,如果我雜交兩種,儲蓄不會保留數據。

- (void)saveContext { 
    dispatch_async(dispatch_get_main_queue(), ^{ 
    @try { 
     NSError *error = nil; 
     if (![[NSManagedObjectContext MR_defaultContext] save:&error]) { 
      NSLog(@"Failed to save core data: %@", [error localizedDescription]); 
     } else { 
      NSLog(@"\"Successfully\" saved your data."); 
     } 
    } 
    @catch (NSException *exception) { 
     NSLog(@"Couldn't save your data! Try again later :("); 
    } 
    @finally { 
     NSLog(@"Look, I don't know what else to tell you, mang."); 
    } 
    }); 
} 

我真的不知道還有什麼可以嘗試的。任何人都可以將我指向正確的方向嗎?

+0

您應該檢查MR_defaultContext是在'dispatch_async牽強()'塊與你在主線程中創建的塊相同(我有一種感覺不會)。如果沒有,嘗試設置一個指向它的指針並使用^塊內的指針,即__block NSManagedObjectContext * theContext = [NSManagedObjectContext MR_defaultContext];'然後引用塊中的'theContext'。 – Rog

回答

1

那麼,我從來沒有使用MagicalRecord,但我懷疑你的問題與它有任何關係。不幸的是,你沒有提供正確的信息。

具體來說,您的託管對象上下文是什麼?也就是說,self.managedObjectContext返回什麼,以及該上下文是如何創建的?

它與默認MR上下文有什麼關係?我認爲MR做了一些線程特定的上下文映射,所以如果你打算使用MR,你應該堅持MR。

基本上,如果它是相同的上下文,你應該可以,但如果它不是相同的,你將不得不與其他人協調變化。另外,請注意如果您將它創建爲子項,那麼保存子上下文只會將更改推送給父項,而不會將其保存。

此外,請確保您的MOC不是零...一個零MOC將不做任何事情發送保存:消息(或任何消息)。

+0

self.managedObjectContext與MR_defaultContext是相同的內存地址。暗示,既不是零。我將手動設置核心數據堆棧並查看是否改變了任何內容。感謝您的洞察! – Jacob

+0

剛剛添加了樣板CoreData代碼,刪除了所有的MagicalRecord方法,並且它工作得很好。所以我想這是MagicalRecord的線程使用情況,當試圖在自定義的保存方法之外保存上下文時會導致問題。我會繼續並將你的標記作爲答案。再次感謝! – Jacob

+0

您可以使用MR_saveNestedContext再次嘗試嗎?我很肯定它會以這種方式工作。 –

1

MagicalRecord創建它的defaultContext嵌套在另一個稱爲rootSavingContext的大多數是私有的上下文中。結果是在嵌套(子)上下文中調用核心數據的標準保存方法並不是而是寫入磁盤,而只是將其更改傳播回父級rootSavingContext。

基本上,我認爲你有兩個選擇:

  1. 呼叫MR_save,讓MagicalRecord處理它;即:

    [[NSManagedObjectContext MR_defaultContext] MR_save]; 
    
  2. 呼叫的NSManagedObjectContext節省的DefaultContext,然後按照它通過調用保存在父上下文:

    [[NSManagedObjectContext MR_defaultContext] save]; 
    [[NSManagedObjectContext MR_rootSavingContext] save]; 
    
相關問題