iOS应用程序在启动时与objc_release EXC_BAD_ACCESS崩溃

时间:2015-01-09 12:56:46

标签: ios nszombie nszombieenabled

我的应用程序保持(使用ARC)在启动后立即崩溃,并带有以下线程回溯:

enter image description here

enter image description here

奇怪的是,当我尝试使用Instruments-Zombie工具运行应用程序时,该应用程序工作正常并且不会崩溃,但我在仪表板上没有获得僵尸访问通知。如果它在启用僵尸标志的情况下工作正常,我至少会期待看到一个僵尸通知!

有关如何进一步解决此问题的任何想法?

修改

所以这里有一些代码,我设法将问题缩小到特定的代码路径。

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)。

我注意到的两件重要事情:

1)如果我在获取后插入[moc reset],则不再引发异常(这当然不能扩展到我的程序,因为我正在处理NSFetchRequestControllers等)。

2)如果我不使用主对象上下文,而是使用私有队列中的对象上下文,则不会引发异常。

完全回溯:

(lldb)线程回溯

  
      
  • 线程#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.dylib objc_release + 21   帧#1:0x03b3ad32 libobjc.A.dylib (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 586 frame #2: 0x04153678 CoreFoundation _ CFAutoreleasePoolPop + 24   第3帧:0x01123184基金会-[NSAutoreleasePool drain] + 149 frame #4: 0x0379a9ec CoreData _ performRunLoopAction + 348   第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 CoreFoundation CFRunLoopRunInMode + 123   帧#10:0x05c4d24f GraphicsServices GSEventRunModal + 192 frame #11: 0x05c4d08c GraphicsServices GSEventRun + 104   帧#12:0x01de48b6 UIKit UIApplicationMain + 1526 frame #13: 0x000611cd Contacit main(argc = 1,argv = 0xbfff83b0)+ 141 at main.m:16   帧#14:0x0482cac9 libdyld.dylib`start + 1
  •   

因此,非常感谢调查中的任何帮助!

1 个答案:

答案 0 :(得分:1)

显然这是问题的原因...在我扩展的NSManagedObject类中,我已经覆盖了这个方法

- (void)willTurnIntoFault
{
    [super willTurnIntoFault];

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

删除此问题解决了这个问题。