Некоторая информация о том, как я сохраняю свои данные: у меня есть массив контроллеров View, которые добавляются и удаляются пользователем (это в основном приложение для заметок и контроллеры View это папки). Контроллеры просмотра имеют несколько динамических свойств, которые необходимо сохранить приложению, а также массив заметок, а сами объекты Note имеют несколько свойств, которые необходимо сохранить. В View контроллеры и Notes оба, конечно, есть соответствующие вещи NSCoding, это один на View Controller, например:heightForRowAtIndexPath иногда сбой при загрузке, NSCoding - iOS
- (void) encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:self.folderName forKey:@"lvcTitle"];
[encoder encodeObject:[NSNumber numberWithInt:self.myPosition] forKey:@"myPosition"];
[encoder encodeObject:self.notes forKey:@"notes"];
}
- (id)initWithCoder:(NSCoder *)decoder {
self.folderName = [decoder decodeObjectForKey:@"lvcTitle"];
NSNumber *gottenPosition = [decoder decodeObjectForKey:@"myPosition"];
int gottenPositionInt = [gottenPosition intValue];
self.myPosition = gottenPositionInt;
self.notes = [decoder decodeObjectForKey:@"notes"];
return self; }
Массив контроллеров принадлежит к классу Singleton. NSCoding довольно запутанный для меня, хотя он считается простым, но до сих пор я добился успеха только в том, что Singleton сохранил массив Controllers, который затем (успешно) сохраняет все содержащиеся в нем свойства контроллеров View, их свойства и все свойства Notes. Вот код в Singleton:
- (void) saveDataToDisk:(id)object key:(NSString *)key {
NSString *path = [self pathForDataFile];
NSMutableDictionary *rootObject;
rootObject = [NSMutableDictionary dictionary];
[rootObject setValue:object forKey:key];
[NSKeyedArchiver archiveRootObject:rootObject toFile:path]; }
- (void) loadDataFromDisk {
NSString *path = [self pathForDataFile];
NSDictionary *rootObject;
rootObject = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
if ([rootObject valueForKey:@"controllers"] != nil) {
self.controllers = [NSMutableArray arrayWithArray:[rootObject valueForKey:@"controllers"]];
firstRun = false;
LabeledViewController *lastOneThere = [self.controllers objectAtIndex:self.controllers.count-1];
lastOneThere.isFolderAddView = TRUE;
}else{
firstRun = true;
}
}
Я затем вызвать метод сохранения несколько раз в папке View Controllers:
[singleton saveDataToDisk];
И это будет хорошо работать несколько раз, пока я случайно не получаю аварии когда приложение загружается. Вина heightForRowAtIndexPath:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
Note *currentNote = [self.notes objectAtIndex:indexPath.row];
if (currentNote.associatedCellIsSelected) {
return currentNote.myHeight + NOTE_BUTTON_VIEW_HEIGHT;
}
return NORMAL_CELL_FINISHING_HEIGHT; }
Я получаю следующее сообщение об ошибке:
2012-06-07 08:28:33.694 ViewTry[1415:207] -[__NSCFString associatedCellIsSelected]: unrecognized selector sent to instance 0x8904710
2012-06-07 08:28:33.696 ViewTry[1415:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString associatedCellIsSelected]: unrecognized selector sent to instance 0x8904710'
*** First throw call stack:
Я понимаю, что «__NSCFString» и «непризнанный селектор направил к экземпляру» означает, что есть строка где-то там не должен быть, поскольку associatedCellIsSelected - это bool. Однако, если я только возвращаю «currentNote.myHeight» в heightForRow, я также получаю ту же ошибку __NSCF с myHeight, которая является плавающей точкой. Если я вынимаю heightForRow все вместе, все работает, за исключением соответствующих определений высоты.
BTW, вид таблицы, который heightForRowAtIndexPath ссылается на loadView ПОСЛЕ создания массива заметок. Я просто не понимаю, почему эта ошибка появлялась только раз в то время (вроде открытия 5-10, сбережений, закрытия и повторного открытия приложения), казалось бы, случайным - я не могу найти шаблон, который вызывает это поведение. Любые указатели?
Извините за беспорядок, я новичок в программировании на iOS, и я уверен, что делаю здесь много чего не так.
Редактировать - Также, как только приложение разбилось, оно остается разбитым каждый раз, когда я его снова открываю (если я не отключу heightForRow), пока я не удалю его и не переустановить.
...и самый простой способ отладить это - включить зомби. http://stackoverflow.com/questions/5386160/how-to-enable-nszombie-in-xcode –
Простой. После того, как я посмотрел, я нашел в одном методе, что преждевременно сохранял заметку в базе данных прямо перед ее удалением, поэтому, когда приложение открылось, оно искало записку, которой не было. Спасибо Филиппу и Джесси! – Zack