Я новичок в разработке iphone, и я боролся с ошибкой EXC_BAD_ACCESS, которую я получил пару дней назад. Я в основном беру класс iphone из Стэнфорда независимо и пытаюсь передать массив NSManagedObjects в TableViewController, который должен их отображать. Приложение запускается в симуляторе и отображает данные в tableView, но сразу же выдает ошибку EXC_BAD_ACCESS.
Я следовал инструкциям здесь и в других местах о том, как использовать NSZombieEnabled для выявления преждевременно выпущенных объектов, но этот приходит без каких-либо полезных сообщений даже с NSZombieEnabled. Я предполагаю, что это должно быть вызвано тем, что что-то пытается получить доступ к нераспределенной памяти, которая не была освобождена через выпуск/автоматический выпуск. В противном случае он был бы воспринят как объект-зомби, как и другие ошибки, которые мне удалось исправить. Я не эксперт по c, но означает ли это, что что-то подобное может произойти, если я объявлю объект и отправлю ему сообщение, даже не создав его экземпляр? Я просмотрел свой код, чтобы увидеть, есть ли у меня что-то подобное, и я оказался пустым.
У меня есть трассировка стека в отладчике для этого, но я не уверен, как ее использовать. Я немного расстроен, потому что не могу использовать точки останова в коде, чтобы еще больше сузить проблему, поскольку кажется, что это происходит после завершения загрузки приложения. Я думал, что приложение будет просто бездействовать, если не будет возможного взаимодействия с пользователем. Это выходит из строя в конце загрузки, где я не могу легко увидеть это, или просто делаю что-то в фоновом режиме после завершения загрузки. И я был бы очень признателен за любые советы о том, как читать трассировку стека для этого.
Я набрал свою трассировку стека ниже (не мог понять, как скопировать ее из отладчика)
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];
}
Я извиняюсь, если мой код слишком дрянной для чтения.
Спасибо за помощь, ребята!