在没有来自 NSZombieEnabled 的任何有用消息的情况下获取 EXC_BAD_ACCESS
我是 iphone 开发的新手,几天前我一直在努力解决 EXC_BAD_ACCESS 错误。我基本上是独立学习斯坦福大学的 iphone 课程,并且我试图将 NSManagedObjects 数组传递给应该显示它们的 TableViewController 。应用程序在模拟器中启动并在 tableView 中显示数据,但它立即出错并显示 EXC_BAD_ACCESS。
我按照此处和其他地方的说明进行操作,了解如何使用 NSZombieEnabled 来识别过早释放的对象,但即使使用 NSZombieEnabled,此操作也没有任何有用的消息。我的猜测是,它一定是由于尝试访问未通过释放/自动释放释放的未分配内存而引起的。否则它会像我能够修复的其他错误一样被拾取为僵尸对象。我不是交流专家,但这是否意味着如果我声明一个对象并向其发送消息而不实例化它,可能会发生类似的情况?我查看了我的代码,看看是否有类似的东西,结果却一无所获。
我在调试器中有堆栈跟踪,但我不确定如何使用它。我有点沮丧,因为我无法在代码中使用断点来进一步缩小问题范围,因为它似乎是在应用程序完成加载后发生的。我认为如果没有可能的用户交互,应用程序就会保持空闲状态。它是否在加载的尾部失败,我无法轻易看到它,或者加载完成后只是在后台做一些事情。我非常感谢有关如何阅读堆栈跟踪的任何提示。
我在下面输入了我的堆栈跟踪(无法弄清楚如何从调试器复制它)
0 objc_msgSend
1 ??
2 -[NSManagedObject 释放]
3 -[_PFManagedObjectReferenceQueue _processReferenceQue:]
4 _performRunLoopAction
5 ___CFRunLoopDoObservers
6 CFRunLoopRunSpecific
7 CFRunLoopRunIn模式
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];
}
如果我的代码太糟糕而无法阅读,我深表歉意。
谢谢你们的帮助。
I'm a newbie to iphone development and I've been struggling with an EXC_BAD_ACCESS error I got a couple of days ago. I'm basically taking the Stanford iphone class independently and I am trying to pass an array of NSManagedObjects to a TableViewController that's supposed to display them. The application launches in the simulator and displays the data in the tableView but it immediately errors out with an EXC_BAD_ACCESS.
I followed instructions here and other places on how to use NSZombieEnabled to identify prematurely released objects but this one comes without any helpful msgs even with NSZombieEnabled. My guess is it must be caused by something trying to access unassigned memory that wasn't released through release/autorelease. Or else it would have been picked up as zombie object like the other errors I have been able to fix. I'm not a c expert but does that mean something like that could happen if I were to declare an object and send it a message without ever instantiating it? I looked through my code to see if I had anything like that and I came up empty.
I have the stack trace in the debugger for this but I'm not sure how to make use of it. I'm a little frustrated because I can't use breakpoints in the code to narrow down the problem any further since it seems to happen after the app has finished loading. I thought the app would just stay idle if there was no possible user interaction. Is it failing at the tail end of the load where I can't easy see it or is jut doing stuff in the background after it's done loading. And I would much appreciate any tips on how to read the stacktrace for this.
I've typed out my stacktrace below (couldn't figure out how to copy it from the debugger)
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
And the two main classes in my program are the top level delegate class and the ViewTableController it calls.
`- (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];
}
I apologize if my code is too crappy to read.
Thanks for the help guys.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是您的问题:
objectForKey:
返回一个autoreleased
对象,您不应该释放它。同样,
insertNewObjectForEntityForName:inManagedObjectContext:managedObjectContext
返回一个autoreleased
对象,因此删除[image release]
和[contact release]
Here is your problem:
objectForKey:
returns anautoreleased
object, you shouldn't release it.Similarly,
insertNewObjectForEntityForName:inManagedObjectContext:managedObjectContext
returns anautoreleased
object, so remove[image release]
and[contact release]
即使检查了 NSZombieEnabled,我也收到 EXC_BAD_ACCESS,但没有任何有用的消息。所以,我想分享一下这段经历:
在模拟器上挣扎了几个小时后,我决定将其安装到设备上。我通过设备调试得到的错误消息更有帮助。
最终,我注意到我收到了 EXC_BAD_ACCESS 错误和奇怪的行为,因为我前一天重命名了几个xib 文件。我为 MainWindow.xib 文件选择了“视图控制器”对象,并更正了 NIB 名称 属性。然后,一切都很顺利。
I was also getting EXC_BAD_ACCESS without any helpful message even though NSZombieEnabled was checked. So, I would like to share this experience:
After several hours of struggling with the simulator, I decided to install it to the device. The error message that I got from debugging with the device was more helpful.
Eventually, I noticed that I was getting EXC_BAD_ACCESS error and strange behavior because I renamed a couple of xib files a day before. I selected the 'View Controller' object for MainWindow.xib file and corrected the NIB Name property. Then, everything worked smoothly.