ios - iPhone应用程序在退出事件状态后崩溃(核心数据删除后)

标签 ios iphone core-data crash

我的应用程序使用核心数据进行数据存储,并且我添加了处理数据库/模型不兼容/损坏/等情况的代码。在这种情况下,我将显示一条错误消息,提示用户删除所有数据,并重新启动应用程序,以便用户可以从头开始。

问题是,删除存储并且用户按下主页按钮后应用程序将崩溃。我的删除代码如下所示:

// 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;

有趣的是,NSPercientStoreCoordinator 的保留计数为 1,因此上面的释放将释放该对象。

当用户现在按下主页按钮时,我将在控制台中看到以下内容:

*** -[NSPersistentStoreCoordinator retain]: message sent to deallocated instance 0x8345530

本例中打印的地址0x8345530等于上面代码中释放的NSPercientStoreCoordinator对象。回溯看起来像这样:

(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

完全重新启动后,应用程序当然会再次正常工作,并带有一个全新的空存储文件。

上面的代码来 self 的应用程序委托(delegate)子类,属性声明如下:

@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;


@synthesize managedObjectContext = __managedObjectContext;
@synthesize persistentStoreCoordinator = __persistentStoreCoordinator;

我只是不明白的是,当保留计数明显达到零时,任何对象如何仍然使用旧存储协调器实例?我从来没有在应用程序委托(delegate)类之外使用/访问此对象。

[编辑]刚刚运行了仪器(僵尸模式),产生了类似的结果:

http://i41.tinypic.com/317ci91.jpg

从回溯中可以看出,某些清除缓存方法导致了崩溃。它是什么,如何让它使用新的存储协调器实例,而不是僵尸实例?

最佳答案

您是否尝试过[self saveContext];并在应用终止之前将其放入applicationWillTerminate:中。并且您不应该使用 retainCount 来查看对象是否过度释放或过度保留。您应该使用 Instrument 来代替

关于ios - iPhone应用程序在退出事件状态后崩溃(核心数据删除后),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9759893/

相关文章:

ios - 1 个屏幕包含 2 个 View Controller 的最佳方法

ios - 扑克手排名循环组合

iphone - 当 View 不是全屏时,子类化 UIViewController 或创建自定义 NSObject

ios - documents目录下的Core Data sqlite数据库是iCloud自动备份的吗?

cocoa - 以编程方式绑定(bind) NSTableView

html - 表格布局 :fixed behaves odd on iPhone

linux - 来自 iOS 的 OPTIONS 请求

ios - 如何在 Json 请求中的参数中传递一个 ID 数组

iphone - 用于在 Mac 上全新安装的最新 XCode .dmg(安装程序)

iOS CoreData - 序列化整个对象而不是创建实体