I’ve created a small class that loads dictionary items from a plist file. The getSettingForKey method works the first time I call the static method, however after a few more calls the dictionary throws a SIGABRT exception for a call with the same key that worked on a previous call. Any ideas?
static NSDictionary *dictionary = nil;
static NSLock *dictionaryLock;
@implementation ApplicationSettingsHelper
+ (void) initialize
{
dictionaryLock = [[NSLock alloc] init];
// Read plist from application bundle.
NSString *path = [[NSBundle mainBundle] bundlePath];
NSString *finalPath = [path stringByAppendingPathComponent:@"Xxxx.plist"];
dictionary = [NSDictionary dictionaryWithContentsOfFile:finalPath];
// dump the contents of the dictionary to the console.
for(id key in dictionary)
{
NSLog(@"bundle: key=%@, value=%@", key, [dictionary objectForKey:key]);
}
}
+ (NSDictionary *)dictionaryItems
{
[dictionaryLock lock];
if (dictionary == nil)
{
[self initialize];
}
[dictionaryLock unlock];
return dictionary;
}
+(id)getSettingForKey:(NSString *)key
{
return [[self dictionaryItems] objectForKey:key];
}
@end
Moshe – I’ve taken your suggestion and updated to use NSUserDefaults instead:
+ (void)load
{
// Load the default values for the user defaults
NSString* pathToUserDefaultsValues = [[NSBundle mainBundle]
pathForResource:@"Xxxx"
ofType:@"plist"];
NSDictionary* userDefaultsValues = [NSDictionary dictionaryWithContentsOfFile:pathToUserDefaultsValues];
// Set them in the standard user defaults
[[NSUserDefaults standardUserDefaults] registerDefaults:userDefaultsValues];
}
+ (id)getSettingForKey:(NSString *)key
{
return [[NSUserDefaults standardUserDefaults] valueForKey:key];
}
Your dictionary has probably been deallocated, causing an invalid memory access. When you create a dictionary using the
dictionaryWithContentsOfFile:method, it is autoreleased, which means it will automatically be released in the future. Since you never retain the dictionary, that release will cause the dictionary to be deallocated.Also, most of your
dictionaryItemsmethod is useless.The
+initializemethod is automatically called by the runtime before any other method is called on your class, unless you have a+loadmethod. Since the runtime will call it for you and it will attempt to create the dictionary, the dictionary can only be nil in thedictionaryItemsmethod if there wasn’t enough memory to create it, in which case it will fail again. Also, if you don’t use the lock anywhere else, it is unnecessary also, since removing that check would cause it to be locked and immediately unlocked. Therefore, you can remove the lock and change yourdictionaryItemsmethod to simply: