это один из многих вопросов EXC_BADACCES, но я долгое время проводил исследования и думаю, что на этот вопрос еще не ответили. Мое приложение сохраняет данные в настройках. Все идет хорошо, если я удаляю настройки и запускаю приложение, чтобы вообще не происходила загрузка. Но если загрузка происходит, возникает проблема. Я должен сохранить один основной массив, который содержит самописные объекты, называемые Box. Один ящик имеет NSString * boxName и шесть NSMutableArray *, которые содержат другой самописанный объект, называемый Flashcard, который содержит два NSString *: вопрос и ответ. Если AppDelegate получает сообщение applicationWillTerminate, он кодирует основной массив (называемый boxArray) с помощью NSKeyedArchiver и сохраняет его в настройках. В методе init 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"];
Карты кодируются с помощью кодера:
- (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, и он показал точно такую же строку.
В своих исследованиях я установил точки торможения для каждого метода и выяснил, что в init с методом кодера Box все в порядке, и boxName - это то, что должно быть (например, "foo"), но если tableview (Managed NSArrayController) хочет загрузить данные в табличное представление, которое вылетает во время работы или показывает такие вещи, как, например, «1: 918», шаг за шагом. Я уверен, что я не выпустил массив, имя boxName или что-либо еще в процессе загрузки, поэтому я не могу объяснить эту проблему. Я был бы очень рад, если бы вы могли мне помочь, Elefantosque