2010-09-19 8 views
1

J'ai un UITabBarController. L'un des onglets affiche l'application "signets", ces signets sont essentiellement des types de recherche enregistrés dans une base de données Core (SQLLite).Bizarre EXC_BAD_ACCESS, qu'est-ce que je fais mal?

Lorsque je charge mon application, accédez à la vue des signets (bookmarksViewController), elle charge une fonction dans mon appDelegate (getBookmarks) et affiche le résultat dans un tableau. Cela fonctionne parfaitement, peut basculer entre les vues, les recherches de préformes dans d'autres vues revenir en arrière. Aucun problème. Il charge le contenu à chaque fois. MAIS ... lorsque je charge une vue de recherche et que j'ajoute un nouveau signet, puis que je repasse à l'affichage du signet, il disparaît avec le message d'erreur "EXC_BAD_ACCESS". Je n'ai aucune idée de pourquoi et comment je peux résoudre ce problème.

Ceci est mon code:
bookmarksViewController.m

[...] 
- (void)viewDidLoad { 
    [super viewDidLoad]; 

theBookmarks = nil; 

    // Set up the edit and add buttons. 
    self.navigationItem.rightBarButtonItem = self.editButtonItem; 

[self setTitle:NSLocalizedString(@"Bookmarks", @"bookmarksViewController")]; 
} 

- (void)viewWillAppear:(BOOL)animated { 
if (theBookmarks != nil) 
{ 
    NSLog(@"Release it!"); 
    [theBookmarks release]; 
} 

NSLog(@"Appear 1"); 

stationenAppDelegate *stationen = (stationenAppDelegate *)[[UIApplication sharedApplication]delegate]; 

NSLog(@"Appear 1 - stage 2"); 

theBookmarks = [[stationen getBookmarks] retain]; 

NSLog(@"Appear 2"); 

    [super viewWillAppear:animated]; 
} 
[...] 

myAppDelegate.m

[...] 
/** 
* Bookmarks 
* 
* Type definition 
* 1: Station search 
* 2: Train search 
* 3: Interuption search 
*/ 

- (NSMutableArray*)getBookmarks 
{ 
NSLog(@"check 1"); 

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 

NSEntityDescription *entity = [NSEntityDescription entityForName:@"bookmarks" 
      inManagedObjectContext:self.managedObjectContext]; 
[fetchRequest setEntity:entity]; 

NSLog(@"check 2"); 

NSError *error; 
NSArray *items = [[self.managedObjectContext 
     executeFetchRequest:fetchRequest error:&error] retain]; 
NSMutableArray *returnArray = [[[NSMutableArray alloc] initWithArray:items] retain]; 

NSLog(@"check 4"); 

[fetchRequest release]; 

return returnArray; 
} 

- (void)addBookmark:(bookmarks_object*)theBookmark 
{ 
BOOL exists = [self checkIfBookmarkExistsUsingBookmark:theBookmark]; 

if(!exists) 
{ 
    bookmarks *saveBookmark = (bookmarks *)[NSEntityDescription insertNewObjectForEntityForName:@"bookmarks" 
        inManagedObjectContext:self.managedObjectContext]; 

    [saveBookmark setStation_from:theBookmark.station_from]; 
    [saveBookmark setStation_to:theBookmark.station_to]; 
    [saveBookmark setAddDate:[[NSDate alloc] init]]; 
    [saveBookmark setSort:theBookmark.sort]; 
    [saveBookmark setPlace:[[NSNumber alloc] initWithInt:([[self getBookmarks] count]+1)]]; 
    [saveBookmark setName:([theBookmark.type isEqualToString:@"1"] || [theBookmark.type isEqualToString:@"2"] ? theBookmark.station_from : [[NSString alloc] initWithFormat:@"%@ -> %@", theBookmark.station_from, theBookmark.station_to])]; 
    [saveBookmark setType:theBookmark.type]; 

    [self saveAction]; 
    [saveBookmark release]; 
} 
else { 
    NSLog(@"No need to add, %@ already exists!", theBookmark.station_from); 
} 
} 

- (BOOL)checkIfBookmarkExistsUsingBookmark:(bookmarks_object*)theBookmark 
{ 
// Get the categories 
NSArray *historyArray = [self getBookmarks]; 

BOOL exists = NO; 

for(bookmarks *dbHistory in historyArray) 
{ 
    if ([theBookmark.type isEqualToString:@"1"] || [theBookmark.type isEqualToString:@"2"]) 
    { 
    if([[dbHistory station_from] isEqualToString:theBookmark.station_from]) 
    { 
    exists = YES; 
    continue; 
    } 
    } 
    else if ([theBookmark.type isEqualToString:@"3"]) 
    { 
    if([[dbHistory station_from] isEqualToString:theBookmark.station_from] && 
     [[dbHistory station_to] isEqualToString:theBookmark.station_to]) 
    { 
    exists = YES; 
    continue; 
    } 
    } 
    else { 
    NSLog(@"Error! Unknown type!"); 
    return NO; 
    } 
} 

return exists; 
} 
[...] 

Trace de la pile (Flow: application d'ouverture, les signets de charge vue, passer à la recherche afficher, ajouter un signet, revenir)

2010-09-19 13:51:54.554 stationen[7256:207] Appear 1 
2010-09-19 13:51:54.555 stationen[7256:207] Appear 1 - stage 2 
2010-09-19 13:51:54.555 stationen[7256:207] check 1 
2010-09-19 13:51:54.560 stationen[7256:207] check 2 
2010-09-19 13:51:54.562 stationen[7256:207] check 4 
2010-09-19 13:51:54.562 stationen[7256:207] Appear 2 
2010-09-19 13:52:26.669 stationen[7256:207] check 1 
2010-09-19 13:52:26.670 stationen[7256:207] check 2 
2010-09-19 13:52:26.671 stationen[7256:207] check 4 
2010-09-19 13:52:26.671 stationen[7256:207] No need to add, 230 already exists! 
2010-09-19 13:52:30.509 stationen[7256:207] Release it! 
2010-09-19 13:52:30.510 stationen[7256:207] Appear 1 
2010-09-19 13:52:30.510 stationen[7256:207] Appear 1 - stage 2 
Program received signal: “EXC_BAD_ACCESS”. 
+1

S'il vous plaît définir des points de rupture et de vérifier si le résultat de retour de [stationen getBookmarks] est nul ou stationen est nul .. et une raison pour laquelle vous retenez tellement ?! –

+2

avez-vous défini NSZombieEnabled? Il aide grandement lors de la poursuite de ces erreurs: http://iphonedevelopertips.com/debugging/tracking-down-exc_bad_access-errors-with-nszombieenabled.html – Mark

+0

Non, mais je vais jeter un oeil. Thnx –

Répondre

0

Le problème était que l'appDelegate était en quelque sorte sorti entre l'allocation et l'utilisation du temps. J'ajoute une retenue et je la relâche juste après.

Trouvé en utilisant NSZombieEnabled comme suggéré par Mark. Merci!

+0

Oh, je n'ai pas actualisé la page et j'ai commenté le post: D Désolé! – matteodv

+0

Np. C'est juste devenu un peu plus bizarre. J'ai ajouté une autre vue de recherche et la même chose se produit ici. Mais maintenant je retiens l'objet. Le code '' stationenAppDelegate * stationen = (stationenAppDelegate *) [[délégué [UIApplication sharedApplication]]]] '' est désalloué directement. –

+1

Vous ne devez conserver ou libérer le délégué de l'application nulle part. Si vous avez une propriété qui pointe vers le délégué de l'application, faites-lui un 'assign' au lieu de' release' dans la déclaration de propriété. – TechZen

0

Avez-vous essayé d'utiliser Debugger pour voir où se trouve l'erreur?
Dans Xcode, ouvrez le débogueur, puis créez l'application avec des points d'arrêt. Dans le simulateur, faites toutes les étapes pour reproduire l'erreur.
Lorsque vous trouverez l'erreur, le débogueur arrêtera l'application avant qu'elle ne se bloque et vous verrez les méthodes implémentées dans la vue du débogueur ... Un ou plusieurs d'entre eux seront surlignés/écrits en noir. Dans ces méthodes, il y a une erreur. En cliquant dans la méthode, vous verrez où se trouve l'erreur et vous pourrez ensuite modifier ce code pour résoudre l'erreur ...

Espérons que cela puisse vous aider! :)

+0

Oui, j'ai ... et c'est le point qui ne fait pas de différence non plus. Je mets des points d'arrêt à la "vérification 1" et annonce l'appel de la fonction "getBookmarks" dans la vue des signets. Il meurt entre il me semble. –

+1

Malheureusement, je ne suis pas un expert parce que je n'ai jamais développé avant de commencer avec le développement de l'iPhone. Lecture sur le Web, EXC_BAD_ACCESS est un problème commun peut être résolu en utilisant NSZombieEnabled, comme Mark a dit. Vous pouvez jeter un oeil à ces messages: http://www.codza.com/how-to-debug-exc_bad_access-on-iphone et http://www.touch-code-magazine.com/how-to-debug -exc_bad_access/J'espère que cela peut vous aider! ;) – matteodv

Questions connexes