1

私のアプリ (ARC を使用) は、起動直後にクラッシュし、次のスレッドのバックトレースが発生します。

ここに画像の説明を入力

ここに画像の説明を入力

奇妙なことに、Instruments-Zombie ツールを使用してアプリを実行しようとすると、アプリは正常に動作し、クラッシュしませんが、インストルメント パネルにゾンビ アクセスの通知が表示されません。ゾンビ フラグを有効にして問題なく動作する場合は、少なくとも 1 つのゾンビ通知が表示されることを期待します!

この問題にさらにアプローチする方法についてのアイデアはありますか?

編集

ここにいくつかのコードを示します。問題を特定のコード パスに絞り込むことができました。

XYZStore.h/m:

@property (nonatomic,strong,readonly) NSManagedObjectContext* mainManagedObjectContext;

@implementation XYZStore

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (_persistentStoreCoordinator != nil) {
        return _persistentStoreCoordinator;
    }

    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"MyApp.sqlite"];

    NSError *error = nil;
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                             [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                             [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }
    return _persistentStoreCoordinator;
}

- (NSManagedObjectContext *)mainManagedObjectContext
{
    if (_mainManagedObjectContext != nil) {
        return _mainManagedObjectContext;
    }

    _mainManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    _mainManagedObjectContext.persistentStoreCoordinator = [self persistentStoreCoordinator];
    return _mainManagedObjectContext;
}

Initial view controller:


-(void)awakeFromNib
{
    XYZAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
    NSManagedObjectContext *moc= delegate.store.mainManagedObjectContext; // managed context object from XYZStore

    NSEntityDescription *entityDescription = [NSEntityDescription
                                              entityForName:@"Person" inManagedObjectContext:moc];
    NSFetchRequest *request = [[NSFetchRequest alloc] init];

    [request setEntity:entityDescription];

    NSError *error;
    NSArray *results = [moc executeFetchRequest:request error:&error];
    for (id *obj in results) {
        NSLog(@"%p", obj);
    }
    NSLog(@"%d", [results count]); // print "232"
}

このコード パスは、上で添付した例外 (objc_release) をスローします。

私が気づいた2つの重要なこと:

1)[moc reset]フェッチ後に挿入すると、例外は発生しなくなります(NSFetchRequestControllersなどを扱っているため、これはもちろん私のプログラムではスケーラブルではありません)。

2) メイン オブジェクト コンテキストを使用せず、プライベート キュー内のオブジェクト コンテキストを使用すると、例外も発生しません。

完全なバックトレース:

(lldb) スレッドのバックトレース

  • thread #1: tid = 0x9c9a, 0x03b39e85 libobjc.A.dylib objc_release + 21, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xd0000010) * frame #0: 0x03b39e85 libobjc.A.dylibobjc_release + 21 frame #1: 0x03b3ad32 libobjc.A.dylib (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 586 frame #2: 0x04153678 CoreFoundation_CFAutoreleasePoolPop + 24 frame #3: 0x01123184 Foundation -[NSAutoreleasePool drain] + 149 frame #4: 0x0379a9ec CoreData_performRunLoopAction + 348 frame #5: 0x041949de CoreFoundation` CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION
  • 30 フレーム #6: 0x04194920 CoreFoundation __CFRunLoopDoObservers + 400 frame #7: 0x0418a35a CoreFoundation__CFRunLoopRun + 1226 フレーム #8: 0x04189bcb CoreFoundation CFRunLoopRunSpecific + 443 frame #9: 0x041899fb CoreFoundationCFRunLoopRunInMode + 123 フレーム #10: 0x05c4d24f GraphicsServices GSEventRunModal + 192 frame #11: 0x05c4d08c GraphicsServicesGSEventRun + 104 フレーム #12: 0x01de48b6 UIKit UIApplicationMain + 1526 frame #13: 0x000611cd Contacitmain(argc=1, argv=0xbfff80) at main +m14b0 :16 フレーム #14: 0x0482cac9 libdyld.dylib`start + 1

そのため、調査にご協力いただければ幸いです。

4

1 に答える 1

1

どうやらこれが問題の原因だったようです...拡張された NSManagedObject クラスで、このメソッドをオーバーライドしました

- (void)willTurnIntoFault
{
    [super willTurnIntoFault];

    if ([self observationInfo])
    {
        NSLog(@"%@ has observers:\n%@", [self objectID], [self observationInfo]);
    }
}

これを削除すると、問題が修正されました。

于 2015-01-12T16:54:29.703 に答える