【发布时间】:2012-03-18 16:17:36
【问题描述】:
我的应用程序使用核心数据进行数据存储,并且我添加了处理数据库/模型不兼容/损坏/等情况的代码。在这种情况下,我会显示一条错误消息,提示用户擦除所有数据,然后重新启动应用程序,以便用户可以从头开始。
问题是,在删除存储并且用户按下主页按钮后,应用程序将崩溃。我的擦除代码如下所示:
// destroy context
if ([__managedObjectContext hasChanges])
[__managedObjectContext rollback];
[__managedObjectContext release];
__managedObjectContext = nil;
// remove store
if (__persistentStoreCoordinator.persistentStores.count)
[__persistentStoreCoordinator removePersistentStore:[__persistentStoreCoordinator persistentStoreForURL:localURL] error:nil];
NSLog(@"retain count: %p %d", __persistentStoreCoordinator, __persistentStoreCoordinator.retainCount);
[__persistentStoreCoordinator release];
__persistentStoreCoordinator = nil;
有趣的是,NSPersistentStoreCoordinator 的保留计数为 1,因此上面的释放将释放对象。
当用户现在按下主页按钮时,我会在控制台中得到这个:
*** -[NSPersistentStoreCoordinator retain]: message sent to deallocated instance 0x8345530
本例中打印的地址0x8345530等于上面代码中释放的NSPersistentStoreCoordinator对象。回溯如下所示:
(gdb) bt
#0 0x0178be1e in ___forwarding___ ()
#1 0x0178bce2 in __forwarding_prep_0___ ()
#2 0x0122c75e in -[_NSSQLCoreConnectionObsever _purgeCaches:] ()
#3 0x00345a39 in __57-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke_0 ()
#4 0x017f0885 in ___CFXNotificationPost_block_invoke_0 ()
#5 0x017f07a8 in _CFXNotificationPost ()
#6 0x0028a1aa in -[NSNotificationCenter postNotificationName:object:userInfo:] ()
#7 0x005e6169 in -[UIApplication _handleApplicationSuspend:eventInfo:] ()
#8 0x005ee8bd in -[UIApplication handleEvent:withNewEvent:] ()
#9 0x005ef1f8 in -[UIApplication sendEvent:] ()
#10 0x005e2aa9 in _UIApplicationHandleEvent ()
#11 0x01e45fa9 in PurpleEventCallback ()
#12 0x017f91c5 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ ()
#13 0x0175e022 in __CFRunLoopDoSource1 ()
#14 0x0175c90a in __CFRunLoopRun ()
#15 0x0175bdb4 in CFRunLoopRunSpecific ()
#16 0x0175bccb in CFRunLoopRunInMode ()
#17 0x01e44879 in GSEventRunModal ()
#18 0x01e4493e in GSEventRun ()
#19 0x005e0a9b in UIApplicationMain ()
#20 0x000046fd in main (argc=1, argv=0xbffff63c) at main.m:24
在完全重启后,应用程序当然会再次正常工作,使用一个全新的空存储文件。
以上代码来自我的应用委托子类,属性声明如下:
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
@synthesize managedObjectContext = __managedObjectContext;
@synthesize persistentStoreCoordinator = __persistentStoreCoordinator;
我只是不明白的是,当保留计数明显达到零时,任何对象如何仍然使用旧存储协调器实例?我从不在应用委托类之外使用/访问此对象。
[edit] 刚刚运行仪器(僵尸模式),产生类似的结果:
http://i41.tinypic.com/317ci91.jpg
从回溯中可以看出,某些清除缓存方法正在导致崩溃。它是什么,我怎样才能让它使用新的商店协调器实例,而不是僵尸实例?
【问题讨论】:
-
retainCount 没用。不要叫它。
标签: ios iphone core-data crash