2011-01-18 95 views
1

我一直在這個問題上抨擊我的頭幾天無濟於事,失去了所有的理智。 :|iOS崩潰在從後臺恢復後調用NSManagedObjectContext上的回滾

我的應用程序設置爲在活動時和後臺跟蹤設備的位置,我使用CoreData創建和存儲軌道數據。主要CoreData實體是具有許多「RoutePoint」實體的「Route」。當設備從應用程序的CLLocationManager接收到新位置時,新的RoutePoint對象將添加到其父路由中。

當用戶停止跟蹤時,他們可以選擇保存或放棄路由。拋棄路由只需調用[_moc rollback],當然save會調用[_moc save]。我正在使用在AppDelegate上引用我的NSManagedObjectContext實例的方法,而不是在我的任何UIViewControllers中保留或釋放的單例對象。

如果用戶在跟蹤處於活動狀態時將應用程序發送到後臺,則會出現此問題(因此Route和RoutePoint實體實際上未保存到_moc中)。當應用程序返回到活動狀態時,用戶停止路由選擇以放棄應用程序崩潰時的路由(調用「回滾」)。但是,如果重複相同的過程,但用戶保存路由而不是丟棄,則不會發生崩潰並且可以成功保存。咦?

我在gdb得到當這種情況發生的唯一的事情就是EXC_BAD_ACCESS,所以我做了回溯和這裏的結果:

#0 0x34a80464 in objc_msgSend() 
#1 0x356ea6d6 in -[_PFManagedObjectReferenceQueue _processReferenceQueue:]() 
#2 0x356ea3d4 in -[NSManagedObjectContext(_NSInternalNotificationHandling) _processReferenceQueue:]() 
#3 0x356ea084 in -[NSManagedObjectContext(_NSInternalChangeProcessing) _processRecentChanges:]() 
#4 0x3571fb14 in -[NSManagedObjectContext processPendingChanges]() 
#5 0x357603ee in -[NSManagedObjectContext rollback]() 
#6 0x00031862 in -[RouteHistoryDetailViewController discardRoute] (self=0x4a0fc30, _cmd=0x100941) 
#7 0x0003064c in -[RouteHistoryDetailViewController alertView:clickedButtonAtIndex:] (self=0x4a0fc30, _cmd=0x344b7f5f, alertView=0x390aa0, buttonIndex=0) 
#8 0x3445d63e in -[UIAlertView(Private) _buttonClicked:]() 
#9 0x35821fec in -[NSObject(NSObject) performSelector:withObject:withObject:]() 
#10 0x341c84ac in -[UIApplication sendAction:to:from:forEvent:]() 
#11 0x341c844c in -[UIApplication sendAction:toTarget:fromSender:forEvent:]() 
#12 0x341c841e in -[UIControl sendAction:to:forEvent:]() 
#13 0x341c8170 in -[UIControl(Internal) _sendActionsForEvents:withEvent:]() 
#14 0x341c89ce in -[UIControl touchesEnded:withEvent:]() 
#15 0x341be354 in -[UIWindow _sendTouchesForEvent:]() 
#16 0x341bdcce in -[UIWindow sendEvent:]() 
#17 0x341a8fc6 in -[UIApplication sendEvent:]() 
#18 0x341a8906 in _UIApplicationHandleEvent() 
#19 0x320c8f02 in PurpleEventCallback() 
#20 0x3580f6fe in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__() 
#21 0x3580f6c2 in __CFRunLoopDoSource1() 
#22 0x35801f7c in __CFRunLoopRun() 
#23 0x35801c86 in CFRunLoopRunSpecific() 
#24 0x35801b8e in CFRunLoopRunInMode() 
#25 0x320c84aa in GSEventRunModal() 
#26 0x320c8556 in GSEventRun() 
#27 0x341dc328 in -[UIApplication _run]() 
#28 0x341d9e92 in UIApplicationMain() 
#29 0x00002982 in main (argc=1, argv=0x2fdff5a8) 

所以這似乎是一個問題與調用[_moc回滾],但我我做了大量的搜索並嘗試了各種各樣的東西,甚至在UIViewController中保留並釋放了我的MOC實例,但沒有任何工作。很顯然,當應用程序進入後臺時某些事情會出錯,但是它與MOC有關,那麼在保存時也不會發生類似的崩潰?

建議非常感謝! :)

回答

1

我一直只對我的項目有一個標誌,並執行了willResignActive與任何「未確認」項目標誌=真的保存。然後,當我恢復(或啓動),如果我想放棄它們,我可以刪除標誌=真正的地方,並刪除它們......這樣我仍然可以保存或撤消,即使iOS由於內存壓力關閉我的應用程序。

IIRC您目前的設計意味着如果有人打開Safari等,並且您的應用程序關閉,即使用戶想要返回並保存它,因爲更改只在內存中,路由將永久消失。