2011-01-18 107 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等,并且您的应用程序关闭,即使用户想要返回并保存它,因为更改只在内存中,路由将永久消失。