2009-08-30 5 views
5

J'essaie d'écrire dans un fichier plist à l'aide de writeToFile. Avant d'écrire, je vérifie si le fichier existe.Erreur lors de la vérification de l'existence d'un fichier

Voici le code:

#import "WindowController.h" 

@implementation WindowController 

@synthesize contacts; 

NSString *filePath; 
NSFileManager *fileManager; 

- (IBAction)addContactAction:(id)sender { 

    NSDictionary *dict =[NSDictionary dictionaryWithObjectsAndKeys: 
         [txtFirstName stringValue], @"firstName", 
         [txtLastName stringValue], @"lastName", 
         [txtPhoneNumber stringValue], @"phoneNumber", 
         nil]; 

    [arrayContacts addObject:dict]; 

    [self updateFile]; 
} 

- (void)awakeFromNib { 
    NSString *rootPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 
    filePath = [rootPath stringByAppendingPathComponent:@"Contacts.plist"]; 
    fileManager = [NSFileManager defaultManager]; 

    contacts = [[NSMutableArray alloc] init]; 

    if ([fileManager fileExistsAtPath:filePath]) { 

     NSMutableArray *contactsFile = [[NSMutableArray alloc] initWithContentsOfFile:filePath]; 
     for (id contact in contactsFile) { 
      [arrayContacts addObject:contact]; 
     } 
    } 
} 

- (void) updateFile { 
    if (![fileManager fileExistsAtPath:filePath] || [fileManager isWritableFileAtPath:filePath]) { 
     [[arrayContacts arrangedObjects] writeToFile:filePath atomically:YES]; 
    } 
} 

@end 

Lorsque le addContactAction est exécuté, je ne reçois pas d'erreur, mais le programme se termine et il me amène au débogueur. Lorsque j'appuie sur continuer dans le débogueur, je reçois:

Program received signal: “EXC_BAD_ACCESS”. 

Mais ce n'est probablement pas important. PS: Je suis novice en programmation mac et je ne sais pas quoi faire d'autre puisque je ne reçois pas de message d'erreur qui me dit ce qui ne va pas.

Le chemin du fichier est:

/Users/andre/Documents/Contacts.plist

je l'ai déjà essayé ceci (avec le même résultat), mais je lis que vous pouvez seulement écrire dans le dossier des documents:

/Users/andre/Desktop/NN/NSTableView/build/Debug/NSTableView.app/Contents/Resources/Contacts.plist

Est-ce que quelqu'un a une idée ou même une explication pourquoi cela se produit?

Répondre

2

Vous définissez filePath avec la méthode stringByAppendingPathComponent:. Cette méthode renvoie un objet autoreleased. (Objet autoreleased est utilisé après qu'il a été (automatiquement) a publié, ce qui pourrait provoquer l'erreur mauvaise d'accès.)

Je pense que le changement

[rootPath stringByAppendingPathComponent:@"Contacts.plist"]; 

dans

[[rootPath stringByAppendingPathComponent:@"Contacts.plist"] retain]; 

résoudra vos problèmes.

+0

Wow, ça a d'ailleurs réglé mon problème, merci! Pourriez-vous m'en dire un peu plus sur le problème? Je suis sûr que j'ai copié cette ligne de la référence officielle. Merci beaucoup! –

+0

Je vous recommande de jeter un oeil à ce tutoriel: http://cocoadevcentral.com/d/learn_objectivec/. Il a une ligne disant "Pour ce tutoriel, vous pouvez supposer qu'un objet automatique disparaîtra à la fin de la fonction en cours." (Objet automatique étant l'objet auto-libéré).La chaîne que vous avez définie 'disparaît' après la fonction awakeFromNib, donc la variable filePath fait référence à quelque chose qui n'existe plus, provoquant des erreurs. Le conserver ne l'empêchera pas d'être autoreleased, mais fera une copie supplémentaire qui n'est pas libérée jusqu'à ce que vous le disiez. (Ce que vous devriez probablement faire dans -dealloc.) –

+0

André Hoffmann: Apple a un tutoriel bien caché mais très bon sur la gestion de la mémoire Cocoa sur le site ADC. http://developer.apple.com/mac/library/documentation/General/Conceptual/DevPedia-CocoaCore/MemoryManagement.html –

7

D'abord, je pense que vous ne devriez pas instancier un objet NSFileManager. Au lieu de cela, vous utilisez le gestionnaire de fichiers par défaut, comme ceci:

[[NSFileManager defaultManager] fileExistsAtPath: filePath]; 

Ensuite, pourriez-vous préciser à quelle ligne le programme se brise dans le débogueur?

+0

Où puis-je voir à quelle ligne il casse? Il montre seulement le code d'assemblage. Merci pour l'indice avec le gestionnaire de fichiers ... supprimé l'instanciation, mais n'a pas changé une chose. –

+0

Si vous plantez dans le code Cocoa, vous ne verrez que l'assemblage. Sur le côté gauche de la fenêtre du débogueur se trouve une liste de cadres de pile; choisissez-en un qui est dans votre propre code, et vous verrez votre code source, avec la ligne pertinente surlignée en rouge. –

+0

Merci Peter. –

Questions connexes