Pergunta

Sou um novato no desenvolvimento do iPhone e tenho lutado com um erro EXC_BAD_ACCESS que tive alguns dias atrás. Estou basicamente participando da aula de Stanford iPhone de forma independente e estou tentando passar uma variedade de objetos de NsmanAgedObjects para um TableViewController que deveria exibi -los. O aplicativo é iniciado no simulador e exibe os dados no TableView, mas erra imediatamente com um exc_bad_access.

Segui as instruções aqui e outros lugares sobre como usar o NSZombieEnabled para identificar objetos lançados prematuramente, mas este vem sem MSGs úteis, mesmo com o NSZombieEnabled. Meu palpite é que ele deve ser causado por algo tentando acessar a memória não atribuída que não foi lançada através de liberação/autorlease. Ou então teria sido apanhado como um objeto de zumbi como os outros erros que pude corrigir. Não sou especialista em CA, mas isso significa que algo assim poderia acontecer se eu declarar um objeto e enviar uma mensagem sem nunca instantá -la? Eu olhei através do meu código para ver se tinha algo assim e fiquei vazio.

Eu tenho o rastreamento da pilha no depurador para isso, mas não tenho certeza de como fazer uso dela. Estou um pouco frustrado porque não posso usar pontos de interrupção no código para restringir mais o problema, pois parece acontecer depois que o aplicativo terminar de carregar. Eu pensei que o aplicativo permaneceria ocioso se não houvesse interação possível do usuário. Está falhando na extremidade traseira da carga, onde não consigo vê -la com facilidade ou está fazendo coisas em segundo plano depois que terminar o carregamento. E eu apreciaria muito qualquer dica sobre como ler o Stacktrace para isso.

Eu digitei meu Stacktrace abaixo (não consegui descobrir como copiá -lo do depurador)

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

E as duas classes principais do meu programa são a classe Delegate de nível superior e o ViewTableController que ele chama.

`- (void) ApplicationDidfinishlaunching: (uiapplication *) Aplicativo {

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];
}

Peço desculpas se meu código é muito ruim para ler.

Obrigado pela ajuda pessoal.

Foi útil?

Solução

Aqui está o seu problema:

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

objectForKey: retorna um autoreleased Objeto, você não deve liberá -lo.

De forma similar, insertNewObjectForEntityForName:inManagedObjectContext:managedObjectContext retorna um autoreleased objeto, então remova [image release] e [contact release]

Outras dicas

Eu também estava recebendo EXC_BAD_ACCESS sem nenhuma mensagem útil, embora o NSZombieEnabled tenha sido verificado. Então, eu gostaria de compartilhar essa experiência:

Depois de várias horas lutando com o simulador, decidi instalá -lo no dispositivo. A mensagem de erro que recebi ao depurar com o dispositivo foi mais útil.

Eventualmente, notei que estava recebendo erro exc_bad_access e comportamento estranho porque eu renomeado alguns arquivos xib um dia antes. Selecionei o objeto 'View Controller' para o arquivo mainwindow.xib e corrigi o Nome da ponta propriedade. Então, tudo funcionou bem.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top