Приложение iPhone падает после выхода из активного состояния (после стирания основных данных) - PullRequest
0 голосов
/ 18 марта 2012

Мое приложение использует основные данные для хранения данных, и я добавил код, который обрабатывает случаи, когда база данных / модель не совместима / повреждена / и т. Д.В этом случае я выведу сообщение об ошибке, предлагающее пользователю стереть все данные и перезапустить приложение, чтобы пользователь мог начать заново с нуля.

Проблема в том, что приложение вылетаетпосле того, как хранилище было удалено, и пользователь нажал домашнюю кнопку.Мой код очистки выглядит следующим образом:

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

Чего я просто не понимаю, так это как любой объект может по-прежнему использовать экземпляр координатора хранилища OLD, когда retaincount явно достигнет нуля?Я никогда не использую / не получаю доступ к этому объекту вне класса делегата приложения.

[править] Просто запускал инструменты (режим зомби), который дает похожие результаты:

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

Как уже видно из следа, какой-то метод очистки кеша вызывает сбой.Что это такое, и как я могу сделать так, чтобы он использовал экземпляр НОВОГО координатора магазина, а не экземпляр зомби?

1 Ответ

0 голосов
/ 18 марта 2012

вы пробовали [self saveContext]; и поместите его в applicationWillTerminate: до завершения работы приложения. И вы не должны использовать retainCount, чтобы увидеть, перезаписан ли объект. Вы должны использовать инструмент вместо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...