это один из многих вопросов EXC_BADACCES, но я долгое время проводил исследования и думаю, что на этот вопрос еще нет ответа. Мое приложение сохраняет данные в настройках. Все прошло хорошо, если я удалю настройки и запущу приложение, чтобы вообще не было загрузки. Но если происходит загрузка, возникает проблема. Мне нужно сохранить один основной массив, который содержит самописные объекты с именем Box. Один Box имеет NSString* boxName и шесть NSMutableArray*, которые содержат еще один самописный объект, называемый Flashcard, который содержит два NSString*: вопрос и ответ. Если AppDelegate получает сообщение applicationWillTerminate, он кодирует основной массив (называемый boxArray) с помощью NSKeyedArchiver и сохраняет его в настройках. В методе инициализации AppControll этот архив загружается из настроек:
- (id)init {
self = [super init];
if (self) {
// Initialization code here.
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
NSData* archive = [defaults objectForKey:@"boxArray"];
if (archive) {
NSArray* array = [NSKeyedUnarchiver unarchiveObjectWithData:archive];
boxArray = [NSMutableArray arrayWithArray:array];
} else {
boxArray = [[NSMutableArray alloc] init];
}
}
return self;
}
В методе encodeWithCoder Box он создает несколько объектов NSData* для всех своих массивов, например, как здесь.
NSData* p1archv = [NSKeyedArchiver archivedDataWithRootObject:phase1];
[aCoder encodeObject:p1archv forKey:@"phase1"];
и загружает все так: NSData* p1archv = [aDecoder decodeObjectForKey:@"phase1"];
if (p1archv) {
NSArray* a = [NSKeyedUnarchiver unarchiveObjectWithData:p1archv];
phase1 = [NSMutableArray arrayWithArray:a];
NSLog(@"loaded phase1: %@",phase1);
} else {
phase1 = [[NSMutableArray alloc] init];
NSLog(@"inited phase1");
}
Он сохраняет собственное имя ящика следующим образом: [aCoder encodeObject:boxName forKey:@"boxName"]; Загрузка такая:
boxName = [aDecoder decodeObjectForKey:@"boxName"];
Карточки encodeWithCoder:
- (void) encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:question forKey:@"question"];
[aCoder encodeObject:answer forKey:@"answer"];
NSLog(@"encoded %@ and %@",question, answer);
}
и initWithCoder:
- (id) initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self) {
// Initialization code here.
question = [aDecoder decodeObjectForKey:@"question"];
answer = [aDecoder decodeObjectForKey:@"answer"];
}
return self;
}
Хорошо, теперь вы знаете фактическую настройку, но вот в чем моя настоящая проблема:
Если приложение запускается и есть настройки для загрузки, происходит сбой в файле Box.h. Если быть точным, он вылетает в этой строке:
@property (readwrite, copy) NSString* boxName;
с EXC_BAD_ACCESS. Я включил NSZombieEnabled, и он показал точно такую же строку. В своем исследовании я делал точки останова для каждого метода и обнаружил, что в методе инициализации с кодером Box все в порядке, и boxName - это то, что должно быть (например, "foo"), но если табличное представление (управляемое с помощью NSArrayController) хочет загрузить данные в табличное представление, которое падает во время работы или показывает такие вещи, как, например, «1:918» при пошаговом выполнении отдельных шагов. Я уверен, что не освобождал ни массив, ни boxName, ни что-то еще в процессе загрузки, поэтому я не могу объяснить эту проблему. Я был бы очень рад, если бы вы могли мне помочь, Элефантоск