views:

731

answers:

4

Everything is working fine until I call the saveFile method (shown below) to write the file back to disk, where it crashes. What am I doing wrong?

This is part of my viewDidLoad method where I open the file, which works fine.

//Get The Path
[self initPath];

dictionary = [[NSMutableDictionary alloc] initWithContentsOfFile:accountsFilePath];      

if (accountsArray == nil) {
    accountsArray = [[[NSMutableArray alloc]init] autorelease];
}

if (countArray == nil) {     
    countArray = [[[NSMutableArray alloc]init] autorelease];
}

countArray = [dictionary objectForKey:@"count"];
accountsArray = [dictionary objectForKey:@"username"];

Then I load it into a tableview. I then add some new items to it, which works fine. Then I call this method to save it and it crashes:

-(void)saveFile {
    [dictionary setObject:accountsArray forKey:@"username"];
    [dictionary setObject:countArray forKey:@"count"];
    [dictionary writeToFile:accountsFilePath atomically:YES];   
}
A: 

Are all your variables in scope? I assume accountsFilePath and dictionary are class variables? If not they might die at the end of viewDidLoad.

The other thing that might bite you is the capacity of your dictionary is too small, or that the iPhone doesn't like you using the setObject method to overwrite key/value pairs like that. Perhaps try calling removeObjectForKey: and then add it back as you have above?

Tim Bowen
Everything is in scope and yes the files you asked about are class vars. There is no problem with setObject lines, they work. I can comment out just the [dictionary writeToFile:accountsFilePath atomically:YES] line and everything will work so it's that last line that causing the crash.
Xcoder
Anyone else have any ideas?
Xcoder
A: 

You probably already did this, but I would inspect dictionary and accountsFilePath in gdb or by using NSLog right before the writeToFile:atomically: call.

You also might want to share more surrounding code to show what else is going on with respect to this dictionary.

I've been using NSZombie with much success for debugging random crashes as well.

hanleyp
yep, checked all that
Xcoder
+1  A: 

You are autoreleasing countArray and accountsArray just after initializing them. Thet may well be already released when you try to save them. Try commenting the autorelease for both of them (and remember to release them somewhere, maybe in the dealloc method).

Marco Mustapic
yep, tried that. Still crashing
Xcoder
A: 

// what if the path is not found, file is not load and in turn dictionary is nil

dictionary = [[NSMutableDictionary alloc] initWithContentsOfFile:accountsFilePath];

// first time you create accountsArray, countArray

if (accountsArray == nil) {
    accountsArray = [[[NSMutableArray alloc]init] autorelease]; }

if (countArray == nil) {     
    countArray = [[[NSMutableArray alloc]init] autorelease]; }

// hey why you assign accountsArray to a new one again, what about the old one you just init?

// if dictionary is nil, countarray will be nil too

countArray = [dictionary objectForKey:@"count"];
accountsArray = [dictionary objectForKey:@"username"];

//// //// ////////////////////////////////////////////////////////////////

what is your crash message?

what is your accountsFilePath

can you read the dictionary file?

one thing you may want to know

writeToFile will not create a new folder for you

so all folder in accountsFilePath is a must to be exist.

otherwise you may want to create that folder using nsfilemanager

Hikaru
For some reason, and I don't know why, It would never keep the filepath in the var I set it. Weird... In the method I call and create it I would do and NSLog and it would show the path, yet when I did an NSLog in this method it would be empty. So, I ended up writing that path to the userdefaults and it would read that. I still would like to know why it would never stay in the class NSString var I created for it though. Puzzling!?
Xcoder
can you show me how you create that nsstring?
Hikaru