3

我是 iphone 开发的新手,我一直在努力解决几天前遇到的 EXC_BAD_ACCESS 错误。我基本上是独立学习斯坦福 iphone 课程,我试图将一组 NSManagedObjects 传递给应该显示它们的 TableViewController。应用程序在模拟器中启动并在 tableView 中显示数据,但它立即出错并出现 EXC_BAD_ACCESS。

我按照此处和其他地方的说明操作,了解如何使用 NSZombieEnabled 来识别过早释放的对象,但即使使用 NSZombieEnabled,这个也没有任何有用的消息。我的猜测是它一定是由试图访问未通过释放/自动释放释放的未分配内存引起的。否则它会像我能够修复的其他错误一样被当作僵尸对象。我不是交流专家,但这是否意味着如果我要声明一个对象并在没有实例化它的情况下向它发送消息时会发生类似的事情?我查看了我的代码,看看我是否有类似的东西,但结果却是空的。

我在调试器中有堆栈跟踪,但我不知道如何使用它。我有点沮丧,因为我不能在代码中使用断点来进一步缩小问题范围,因为它似乎发生在应用程序完成加载之后。我认为如果没有可能的用户交互,该应用程序将保持空闲状态。它是在加载的尾端失败,我无法轻易看到它,还是在加载完成后在后台做一些事情。我非常感谢有关如何阅读堆栈跟踪的任何提示。

我在下面输入了我的堆栈跟踪(无法弄清楚如何从调试器中复制它)

0 objc_msgSend
1 ??
2 -[NSManagedObject dealloc]
3 -[_PFManagedObjectReferenceQueue _processReferenceQue:]
4 _performRunLoopAction
5 ___CFRunLoopDoObservers
6 CFRunLoopRunSpecific
7 CFRunLoopRunInMode
8 GSEventRunModal
9 GSEventRun
10 UIApplicationMain
11 main

我的程序中的两个主要类是顶级委托类和它调用的 ViewTableController。

`- (void)applicationDidFinishLaunching:(UIApplication *)application {

self.tabBarController = [[[UITabBarController alloc] init] autorelease];        

UINavigationController *contactsNavigationController = [[self createContactsNavigationController] retain];

//UINavigationController *recentsNavigationController = [[self createRecentsNavigationController:photos] retain];

tabBarController.viewControllers = [[NSArray alloc] initWithObjects: contactsNavigationController, nil];

[contactsNavigationController release];
//[recentsNavigationController release];

[window addSubview:tabBarController.view];
    [window makeKeyAndVisible];

}

-(UINavigationController *)createContactsNavigationController {

UINavigationController *contactsNavigationController = [[UINavigationController alloc] init];

UITabBarItem *contactsTabBarItem = [[UITabBarItem alloc] initWithTabBarSystemItem: UITabBarSystemItemContacts tag:0];
contactsNavigationController.tabBarItem=contactsTabBarItem ;
[contactsTabBarItem  release];


PersonListViewController *personListViewController = [[PersonListViewController alloc] initWithStyle:UITableViewStylePlain];    

NSManagedObjectContext *context = [self managedObjectContext];
personListViewController.managedObjectContext=context;

personListViewController.contacts = [self createContacts];
[context release];

personListViewController.title=@"Contacts";

[contactsNavigationController pushViewController:personListViewController animated:false];
return [contactsNavigationController autorelease];

}`

`- (NSArray *)readContacts {

NSString *path = [[NSBundle mainBundle] bundlePath];

NSString *filePath = [path stringByAppendingPathComponent:@"FakeData.plist"];
NSArray *plist = [[NSMutableArray arrayWithContentsOfFile:filePath] retain];

return [plist autorelease];
}

- (NSMutableArray *)createContacts {

NSArray * plist = [[self readContacts] retain
NSMutableArray *contactNames = [[NSMutableArray alloc] init];
NSMutableArray *contacts = [[NSMutableArray alloc] init];
for (NSDictionary *photo in plist) {
    NSString *contactName = [photo objectForKey:@"user"];
    Person *contact = nil;
    if (![contactNames containsObject:contactName]) {
        contact  = (Person *)[NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:managedObjectContext];
        contact.name =contactName;
        NSError *error;
        if (![managedObjectContext save:&error]) {
            NSLog(@"SHIT the save person FAILED!!!  %@",error);
        }

        [contacts addObject:contact];
        [contactNames addObject:contactName];



    } else {
        contact = [contacts objectAtIndex:[contactNames indexOfObject:contactName]];
    }

    [contactName release];

    Photo *image = (Photo *)[NSEntityDescription insertNewObjectForEntityForName:@"Photo" inManagedObjectContext:managedObjectContext];

    image.imageFile = [photo objectForKey:@"path"];
    image.imageName = [photo objectForKey:@"name"];
    image.owner = contact;

    contact.photos = [NSSet setWithObjects:image,nil];


     NSError *error;
     if (![managedObjectContext save:&error]) {
         NSLog(@"SHIT the save photoFAILED!!!  %@",error);
     }

    [image release];
    [contact release];
}

[plist release];

return [contacts autorelease];
}

如果我的代码太糟糕而无法阅读,我深表歉意。

谢谢你们的帮助。

4

2 回答 2

7

这是你的问题:

NSString *contactName = [photo objectForKey:@"user"];
... a bunch of lines later
[contactName release];

objectForKey:返回一个autoreleased对象,你不应该释放它。

同样,insertNewObjectForEntityForName:inManagedObjectContext:managedObjectContext返回一个autoreleased对象,所以删除[image release][contact release]

于 2010-03-17T03:31:01.563 回答
0

即使检查了 NSZombieEnabled,我也收到 EXC_BAD_ACCESS 没有任何有用的消息。所以,我想分享一下这个经验:

经过几个小时的模拟器努力,我决定将它安装到设备上。我从设备调试中得到的错误消息更有帮助。

最终,我注意到我收到了 EXC_BAD_ACCESS 错误和奇怪的行为,因为我在前一天重命名了几个xib 文件。我为 MainWindow.xib 文件选择了“视图控制器”对象并更正了NIB 名称属性。然后,一切顺利。

于 2012-08-01T19:43:01.240 回答