2012-06-05 5 views
1

Некоторая информация о том, как я сохраняю свои данные: у меня есть массив контроллеров 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), пока я не удалю его и не переустановить.

ответ

1

Если вы видите ошибку «непризнанный селектор», и тип приемника не является типом объекта, который вы закодировали (в данном случае __NSCFString вместо Note), вероятность того, что у вас есть проблема, когда объект, на который вы намеревались использование было преждевременно выпущено, и его адресное пространство повторно используется для выделения нового объекта.

Исправление зависит от отслеживания, где происходит дополнительный выпуск (или сохранения не происходит). Если вы можете показать объявление @property для notes, это может проливать больше света на ситуацию.

Одна из быстрых задач - выбрать продукт-> проанализировать из меню и исправить все, что оно обозначает. Это не поймает все, но это хорошая проверка здравомыслия, чтобы начать.

+0

...и самый простой способ отладить это - включить зомби. http://stackoverflow.com/questions/5386160/how-to-enable-nszombie-in-xcode –

+0

Простой. После того, как я посмотрел, я нашел в одном методе, что преждевременно сохранял заметку в базе данных прямо перед ее удалением, поэтому, когда приложение открылось, оно искало записку, которой не было. Спасибо Филиппу и Джесси! – Zack

Смежные вопросы