2013-04-05 118 views
6

我正在使用核心數據,並發現應用程序有時從後臺恢復後崩潰。當我嘗試訪問NSManagedObject子類的屬性時,我發現塊方法體內發生了崩潰。從後臺恢復後訪問核心數據NSManagedObject崩潰應用程序

我有一個財產,持有對NSManagedObject子類的引用。

@property(nonatomic,strong)CalItem * calObject;

要重現崩潰我先需要致電孩子的viewController(NoteViewController)傳遞一個塊(NoteTextBlock)。

NoteViewController *noteViewController = [[NoteViewController alloc]initWithNote:self.calObject.note NoteTextBlock:^(NSString *noteText) { 
        self.calObject.note = noteText; //crashing here 
       }]; 

然後發送應用程序到背景並恢復它。 之後在NoteViewController中,我會向調用viewController返回一條消息。

if (self.noteTextBlock) 
{ 
self.noteTextBlock(trimmedString); 
} 

當塊返回和線self.calObject.note = noteText被執行的應用程序崩潰。

因此,顯然你不能把一個塊放在堆棧上,然後恢復應用程序,然後繼續塊內定義的內容?或者我在這裏做錯了什麼?

編輯:
*** Terminating app due to uncaught exception 'NSObjectInaccessibleException', reason: 'CoreData could not fulfill a fault for '0xb253100 <x-coredata://C2304B7C-7D51-4453-9993-D33B9113A7A5/DTODay/p57>''

塊定義這樣子內的viewController:

@property(nonatomic, copy)NoteTextBlock noteTextBlock; 

EDIT2
這是我所得到的,當我設置一個斷點上它崩潰的路線。
(lldb) po self.calObject
$2 = 0x0b4464d0 <DTODay: 0xb4464d0> (entity: DTODay; id: 0xb489d00 <x-coredata://C2304B7C-7D51-4453-9993-D33B9113A7A5/DTODay/p57> ; data: <fault>)

我使用MagicalRecord LIB來管理所有的核心數據的東西。

- (void)applicationDidBecomeActive:(UIApplication *)application 
{ 
    if ([NSManagedObjectContext MR_defaultContext] == nil 
     || [NSManagedObjectModel MR_defaultManagedObjectModel] == nil 
     || [NSPersistentStoreCoordinator MR_defaultStoreCoordinator] == nil 
     || [NSPersistentStore MR_defaultPersistentStore] == nil 
     ) 
    { 
     //coming back from background, re-init coredata stack 
     [MagicalRecordHelpers setupCoreDataStackWithAutoMigratingSqliteStoreNamed:DBNAME]; 
    } 
+0

你能提供碰撞信息的問題? – 2013-04-05 11:59:32

+0

崩潰前calObject的managedObjectContext是什麼?它是零嗎? – 2013-04-05 12:05:12

+0

只有當應用程序退出並在使用塊作爲回調中恢復時,問題纔會發生。在其他情況下,我可以完全恢復並繼續使用calObject,而不會出現任何問題。不知怎的,塊中的塊或「自我」不能正確保留? – Oysio 2013-04-05 12:11:51

回答

2

我不熟悉MagicalRecords,但是...當你有一個非故障(如可在EDIT 2中可以看出)不再(或從未有過的)對象

,引發此異常存在於商店中。
這可能發生在少數情況下:

  1. 另一個方面已經從
  2. 你已經插入它存儲中刪除它,獲得一個永久編號爲它和:
    **刷新它
    **救了它(但僅限於父上下文),reseted父,並刷新在當前上下文對象(或進口作爲故障到您的主上下文),見objectWithID:

我可能會忘記或不知道其他情況。

,如果你能描述你的堆疊結構,和你的對象狀態/起源,我們也許能夠更好地瞭解

2

嘗試也節省了backgound狀態,然後在你的AppDelegate.m上喚醒恢復狀態

- (void)applicationDidEnterBackground:(UIApplication *)application { 
     /* 
     Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 
     Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 
     */ 
     [MagicalRecord cleanUp]; 
} 





    - (void) applicationDidBecomeActive:(UIApplication *)application { 
     /* 
     Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 
     */ 
     [MagicalRecord setupCoreDataStackWithStoreNamed:DBNAME]; 
} 
0

我從來沒有使用神奇紀錄,但在我看來,你是重建現有的核心數據堆棧,當應用程序再次激活時。我想象你真正想要做的是在applicationDidFinishLaunching:(UIApplication *)而不是applicationDidBecomeActive:(UIApplication *)中設置核心數據。

前者只會在應用程序啓動時設置堆棧,而後者會在每次應用程序「醒來」時重新設置堆棧。

問題是,您已經創建了一個新的Core Data堆棧,同時擁有引用舊的Core Data堆棧的對象。

通常,當應用程序啓動時,您想要創建您的堆棧。當應用程序終止時,您可以嘗試乾淨地取下堆棧。但是,當它剛剛進入後臺時,您應該簡單地保存數據,然後當應用程序被簡單地重新激活時,您無需執行任何操作。

+0

這不會導致異常,只有在沒有保留上下文的情況下孤立對象(所有屬性都將被取消) – 2013-04-14 05:17:55