【问题标题】:iPhone app crashes after resigning active state (after core data wipe)iPhone 应用程序在退出活动状态后崩溃(核心数据擦除后)
【发布时间】: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


【解决方案1】:

您是否尝试过[self saveContext]; 并在应用程序终止之前将其放入applicationWillTerminate:。而且您不应该使用retainCount 来查看对象是否被过度释放或过度保留。你应该改用仪器

【讨论】:

  • 感谢提示,我试试乐器。什么是 [self saveContext]?此外,在没有终止应用程序(只是后台)的情况下出现问题,例如applicationWillTerminate 不会被触发。正如您在上面看到的,我正在查询 managedobjectcontext 以获取待处理的更改,并在销毁对象之前回滚它们。
  • 添加了上面仪器的图片。
  • 我想你想要的是创建一个新的 persistentStoreCoordinator?你用[self persistentStoreCoordinator];了吗?
  • 不,我不想创建新的协调器。问题是,应用程序在访问 OLD、dealloc'ed 协调器时崩溃,我不知道为什么/在哪里。
  • 因为你有dealloc它并且从不初始化?你如何尝试访问persistentStoreCoordinator,如何将_persistentStoreCoordinator更改为[self persistentStoreCoordinator]
猜你喜欢
  • 2011-01-28
  • 2011-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 2016-06-13
相关资源
最近更新 更多