我创建了一个从plist文件加载字典项的小类。 getSettingForKey方法在我第一次调用静态方法时工作,但是在多次调用之后,字典会为具有在先前调用上工作的相同键的调用抛出SIGABRT异常。有什么想法吗?
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 - 我已采纳您的建议并更新为使用NSUserDefaults:
+ (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];
}
答案 0 :(得分:8)
您的字典可能已被取消分配,导致无效的内存访问。使用dictionaryWithContentsOfFile:
方法创建字典时,它是自动释放的,这意味着它将来会自动释放。由于您从不保留字典,因此该版本将导致字典被解除分配。
此外,您的大部分dictionaryItems
方法都无用。
[dictionaryLock lock];
if (dictionary == nil) {
[self initialize];
}
[dictionaryLock unlock];
除非您使用+initialize
方法,否则在您的类上调用任何其他方法之前,运行时会自动调用+load
方法。由于运行时将为您调用它并且它将尝试创建字典,因此如果没有足够的内存来创建字典,则字典在dictionaryItems
方法中只能是nil,在这种情况下它将再次失败。此外,如果您不在其他任何地方使用锁,也不必使用,因为删除该检查会导致锁定并立即解锁。因此,您可以移除锁定并将dictionaryItems
方法更改为:
+ (NSDictionary *)dictionaryItems {
return dictionary;
}
答案 1 :(得分:2)
除了@ ughoavgfhw的答案之外,您还在锁定它之后初始化dictionaryLock
。除非您在其他地方初始化dictionaryLock
,否则我会惊讶于您的代码已经达到了目标。
编辑:我从@ ughoavgfhw的编辑中看到+initialize
之前被调用,所以你的锁在那里被初始化。