views:

40

answers:

1

I'm getting tonnes of EXC_BAD_ACCESS errors related to the following two functions for reading and writing to plist files. I think its memory related. Any suggestions?

+(NSString *) getSettingString: (NSString *)key defaultValue:(NSString *)defValue
{
    NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *path = [[pathArray objectAtIndex:0] stringByAppendingFormat:@"FSSettings_v3.plist"];
    [pathArray release];
    BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:path];
    if (fileExists == YES) {
        NSMutableDictionary* plistDictionary = [NSMutableDictionary dictionaryWithContentsOfFile:path];
        NSString *value =  [plistDictionary objectForKey:key];
        return value;
    } else {
        [self setSettingString:key value:defValue];
        return defValue;
    }

}

+(void) setSettingString: (NSString *)key value:(NSString *)value
{
    NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *path = [[pathArray objectAtIndex:0] stringByAppendingFormat:@"FSSettings_v3.plist"];
    BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:path];
    if (fileExists == YES) {
        NSMutableDictionary* plistDictionary = [NSMutableDictionary dictionaryWithContentsOfFile:path];
        [plistDictionary setObject:value forKey:key];
        [plistDictionary writeToFile:path atomically:YES];
        [plistDictionary release];
    } else {
        NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
        [dict setObject:value forKey:key];
        [dict writeToFile:path atomically:YES];
        [dict release];
    }
    [pathArray release];
}
+2  A: 

You shouldn't release pathArray in the first method:

NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [[pathArray objectAtIndex:0] stringByAppendingFormat:@"FSSettings_v3.plist"];
[pathArray release];

NSSearchNSSearchPathForDirectoriesInDomains returns an autoreleased object. Always do "Build&Analyze" in the XCode. It will tell you many retain/release problems.

That said, don't re-invent the wheel. You can just use NSUserDefaults. Your code becomes four lines:

+(NSString *) settingString: (NSString *)key defaultValue:(NSString *)defValue
{
       NSString*v=[[NSUserDefaults standardUserDefaults] stringForKey:key];
       if(v){
             return v;
       }else{
             return defValue;
       }
}

+(void) setSettingString: (NSString *)key value:(NSString *)value
{
       [[NSUserDefaults standardUserDefaults] setObject:value forKey:key]
}

I would register the default to the NSUserDefaults using registerDefaults:, instead of supplying it to -getSettingString.

Finally, you shouldn't put get in the name of the getter. That's against the custom of Objective-C. In Objective-C, get is typically used only when the result is returned through a pointer passed in as the argument of the method, as in -[NSData getBytes:length:].

Yuji