В моем приложении есть синглтон SettingsManager, который должен позаботиться о чтении / записи настроек в plist. Синглтон синтезируется с использованием макроса из Cocoa With Love ( zip-файл макроса ). Я только изменил тип возврата для сохранения (односторонний доступ) с (недействительный). Это связано с новым компилятором в iOS, который может позаботиться об управлении памятью. Моя проблема в том, что всякий раз, когда я вызываю savePrefs, кнопка вызова селектора «зависает» в активном состоянии, а иногда я получаю EXC_BAD_ACCESS. Так что я думаю, что мне не удалось с управлением памятью. Удивительно, но когда файл plist недоступен (сразу после установки приложения), все значения по умолчанию правильно сохраняются и извлекаются из моего NSMutableDictionary. Ниже мой код. Буду супер признателен за вашу помощь.
Martin
КОД:
1 / Singleton header
#import <Foundation/Foundation.h>
#define SALARY_PREF_KEY @"MonthlySalary"
#define DEFAULT_SALARY [NSNumber numberWithDouble: 0.0]
#define CURRENCY_PREF_KEY @"Currency"
#define DEFAULT_CURRENCY @"USD"
#define EXPENSES_PREF_KEY @"Expenses"
#define DEFAULT_EXPENSES [NSNumber numberWithDouble: 0.0]
#define TIME_INTERVAL_PREF_KEY @"TimeInterval"
#define DEFAULT_INTERVAL [NSNumber numberWithInteger: 2]
#define SAVINGS_PREF_KEY @"Savings"
#define DEFAULT_SAVINGS [NSNumber numberWithDouble: 0.0]
@interface SettingsManager : NSObject {
NSString *prefsFilePath;
NSMutableDictionary *settingsDictionary;
NSNumber *salary;
NSString *currency;
NSNumber *expenses;
NSNumber *timeInterval;
NSNumber *savings;
}
+ (SettingsManager *)sharedSettingsManager;
@property (nonatomic, retain) NSString *prefsFilePath;
@property (nonatomic, retain) NSMutableDictionary *settingsDictionary;
@property (nonatomic, retain) NSNumber *salary;
@property (nonatomic, retain) NSString *currency;
@property (nonatomic, retain) NSNumber *expenses;
@property (nonatomic, retain) NSNumber *timeInterval;
@property (nonatomic, retain) NSNumber *savings;
- (void) savePrefs;
@end
2 / Реализация:
#import "SynthesizeSingleton.h"
#import "SettingsManager.h"
@implementation SettingsManager
SYNTHESIZE_SINGLETON_FOR_CLASS(SettingsManager);
@synthesize settingsDictionary,
salary,
currency,
expenses,
timeInterval,
savings,
prefsFilePath;
- (id)init {
self = [super init];
if (self) {
if (prefsFilePath == nil) {
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex: 0];
prefsFilePath = [documentsDirectory stringByAppendingPathComponent:@"iEarn.plist"];
}
if ([[NSFileManager defaultManager] fileExistsAtPath: prefsFilePath]) {
settingsDictionary = [[NSMutableDictionary alloc]
initWithContentsOfFile: prefsFilePath];
}
else {
settingsDictionary = [[NSMutableDictionary alloc] initWithCapacity: 7];
[settingsDictionary setObject: DEFAULT_SALARY forKey: SALARY_PREF_KEY];
[settingsDictionary setObject: DEFAULT_CURRENCY forKey: CURRENCY_PREF_KEY];
[settingsDictionary setObject: DEFAULT_EXPENSES forKey: EXPENSES_PREF_KEY];
[settingsDictionary setObject: DEFAULT_INTERVAL forKey: TIME_INTERVAL_PREF_KEY];
[settingsDictionary setObject: DEFAULT_SAVINGS forKey: SAVINGS_PREF_KEY];
[settingsDictionary writeToFile: prefsFilePath atomically: YES];
}
self.salary = [settingsDictionary objectForKey:SALARY_PREF_KEY];
self.currency = [settingsDictionary objectForKey:CURRENCY_PREF_KEY];
self.expenses = [settingsDictionary objectForKey:EXPENSES_PREF_KEY];
self.timeInterval = [settingsDictionary objectForKey:TIME_INTERVAL_PREF_KEY];
self.savings = [settingsDictionary objectForKey:SAVINGS_PREF_KEY];
}
return self;
}
- (void) savePrefs {
[settingsDictionary setObject: salary forKey: SALARY_PREF_KEY];
[settingsDictionary setObject: currency forKey: CURRENCY_PREF_KEY];
[settingsDictionary setObject: expenses forKey: EXPENSES_PREF_KEY];
[settingsDictionary setObject: timeInterval forKey: TIME_INTERVAL_PREF_KEY];
[settingsDictionary setObject: savings forKey: SAVINGS_PREF_KEY];
[settingsDictionary writeToFile: prefsFilePath atomically: YES];
}
- (void) dealloc {
[settingsDictionary dealloc];
[super dealloc];
}
@end
3 / Как я звоню savePrefs
- (IBAction)saveButtonPressed:(id)sender {
[[SettingsManager sharedSettingsManager] setSalary: [NSNumber numberWithDouble: [salary.text doubleValue]]];
[[SettingsManager sharedSettingsManager] setCurrency: currency.text];
[[SettingsManager sharedSettingsManager] setExpenses: [NSNumber numberWithDouble: [expenses.text doubleValue]]];
[[SettingsManager sharedSettingsManager] setTimeInterval: [NSNumber numberWithInt: [intervalStepper value]]];
[[SettingsManager sharedSettingsManager] setSavings: [NSNumber numberWithDouble: [savings.text doubleValue]]];
[[SettingsManager sharedSettingsManager] savePrefs];
}