简体   繁体   中英

EXC_BAD_ACCESS with NSUserdefaults on iphone

I have the following code in my ApplicationDelegate. My deployment target is 3.0 and upwards, however I get a EXC_BAD_ACCESS when I launch the app with the following code on my iPhone with 3.1.3, however on the simulator which has 4.2 it runs fine.

This problem is now SOLVED . The code below is working, and it got a EXC_BAD_ACCESS due to a NSURLConnection in my code. I won't delete my code if anyone else get this problem. Thanks for your help.

UPDATE: Plist file:

<dict>
<key>StringsTable</key>
<string>Root</string>
<key>PreferenceSpecifiers</key>
<array>
    <dict>
        <key>Type</key>
        <string>PSGroupSpecifier</string>
        <key>Title</key>
        <string>Check for report on start?</string>
    </dict>
    <dict>
        <key>Type</key>
        <string>PSToggleSwitchSpecifier</string>
        <key>Title</key>
        <string>Autocheck reports?</string>
        <key>Key</key>
        <string>FAutoUpdatePrefKey</string>
        <key>DefaultValue</key>
        <true/>
    </dict>
</array>

Applicationdelegate

+ (void)initialize {

NSString *path = [[NSBundle mainBundle] bundlePath];
NSString *pListPath = [path stringByAppendingPathComponent:@"Settings.bundle/Root.plist"];

NSDictionary *pList = [NSDictionary dictionaryWithContentsOfFile:pListPath];

NSMutableArray *prefsArray = [pList objectForKey:@"PreferenceSpecifiers"];
NSMutableDictionary *regDictionary = [NSMutableDictionary dictionary];

for (NSDictionary *dict in prefsArray) {
    NSString *key = [dict objectForKey:@"Key"];
    if(key) {
        id value = [dict objectForKey:@"DefaultValue"];
        [regDictionary setObject:value forKey:key];
    }
}
[[NSUserDefaults standardUserDefaults] registerDefaults:regDictionary];
}

The registerDefaults: method has been available since iOS 2.0 ( See Documentation ), so that shouldn't be the issue. The problem probably stems from the regDictionary object and how you are filling it.

Take a look at this previous question. The main answer has an excellent method to do what you are trying to accomplish. In fact the code is nearly identical except for how the settings bundle is accessed: Can you make the settings in Settings.bundle default even if you don't open the Settings App

Here is the code you want (Stolen directly from the linked question above from the answer by PCheese )

- (void)registerDefaultsFromSettingsBundle {
    NSString *settingsBundle = [[NSBundle mainBundle] pathForResource:@"Settings" ofType:@"bundle"];
    if(!settingsBundle) {
        NSLog(@"Could not find Settings.bundle");
        return;
    }

    NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[settingsBundle stringByAppendingPathComponent:@"Root.plist"]];
    NSArray *preferences = [settings objectForKey:@"PreferenceSpecifiers"];

    NSMutableDictionary *defaultsToRegister = [[NSMutableDictionary alloc] initWithCapacity:[preferences count]];
    for(NSDictionary *prefSpecification in preferences) {
        NSString *key = [prefSpecification objectForKey:@"Key"];
        if(key) {
            [defaultsToRegister setObject:[prefSpecification objectForKey:@"DefaultValue"] forKey:key];
        }
    }

    [[NSUserDefaults standardUserDefaults] registerDefaults:defaultsToRegister];
    [defaultsToRegister release];
}

UPDATE: Now that I see your pList, Change your PSToggleSwitchSpecifier's default value from <true/> to <string>YES</string>

Try moving the registerDefaults into the loop.

for (NSDictionary *dict in prefsArray) {
       NSString *key = [dict objectForKey:@"Key"];
       if(key) {
           id value = [dict objectForKey:@"DefaultValue"];
           [[NSUserDefaults standardUserDefaults] setObject:value forKey:key]; //<-change               
       }
}

The problem here isn't the difference between OSs, but the difference between device and simulator. Simulator uses Mac OS X file system, which isn't case-sensitive, but the file system on iOS is.

So you might want to double check @"Settings.bundle/Root.plist" and @"PreferenceSpecifiers" if their caps lock is correct.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM