2009-08-30 27 views
5

Estoy tratando de escribir en un archivo plist utilizando writeToFile, antes de escribir compruebo si el archivo existe.Error al comprobar si existe un archivo

Este es el código:

#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 

Cuando se ejecuta el addContactAction no consigo ningún error, pero el programa se detiene y me lleva al depurador. Cuando presiono continue en el depurador, obtengo:

Program received signal: “EXC_BAD_ACCESS”. 

Pero eso probablemente no sea importante.

PS: Soy nuevo en la programación mac y no sé qué más para intentar ya que no aparece un mensaje de error que me dice lo que va mal.

La ruta del archivo es:

/Users/andre/Documents/Contacts.plist

Probé a principios de este (con el mismo resultado), pero he leído que pueda Sólo escribir en la carpeta documentos:

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

¿Alguien tiene una idea o incluso una explicación de por qué sucede esto?

Respuesta

2

Usted está configurando rutaArchivo con el stringByAppendingPathComponent: método. Ese método devuelve un objeto liberado automáticamente. (Objeto autoreleased se utiliza después de que haya sido (de forma automática) dio a conocer, lo que podría provocar que el error de acceso mala.)

Creo que el cambio de

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

en

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

va a resolver sus problemas.

+0

Guau, eso de hecho solucionó mi problema, ¡gracias! ¿Podría decirme un poco más acerca de cuál fue el problema? Estoy bastante seguro de haber copiado esta línea de la referencia oficial. ¡Muchas gracias! –

+0

Te recomiendo que eches un vistazo a este tutorial: http://cocoadevcentral.com/d/learn_objectivec/. Tiene una línea que dice "Para este tutorial, puedes asumir que un objeto automático desaparecerá al final de la función actual". (Objeto automático siendo objeto liberado automáticamente).La cadena que establece 'desaparece' después de la función awakeFromNib, por lo que la variable filePath hace referencia a algo que ya no existe, lo que causa errores. Retenerlo no evitará que se libere automáticamente, sino que hará una copia adicional que no se liberará hasta que se lo indique. (Lo que probablemente debería hacer en -dealloc.) –

+0

André Hoffmann: Apple tiene un tutorial bien oculto pero muy bueno sobre la administración de la memoria Cocoa en el sitio web de ADC. http://developer.apple.com/mac/library/documentation/General/Conceptual/DevPedia-CocoaCore/MemoryManagement.html –

7

En primer lugar, creo que no se debe crear una instancia de un objeto NSFileManager. En lugar de utilizar el gestor de archivos por defecto, así:

[[NSFileManager defaultManager] fileExistsAtPath: filePath]; 

Entonces, ¿podría especificar en qué línea del programa se está rompiendo en el depurador?

+0

¿Dónde puedo ver en qué línea se rompe? Solo muestra el código de ensamblaje. Gracias por la sugerencia con fileManager..removió la creación de instancias, pero no cambió nada. –

+0

Si bloqueas el código de Cocoa, solo verás el ensamblaje. En el lado izquierdo de la ventana del depurador hay una lista de marcos de pila; elija uno que esté en su propio código, y verá su código fuente, con la línea correspondiente resaltada en rojo. –

+0

Gracias Peter. –

Cuestiones relacionadas