heightForRowAtIndexPath偶尔崩溃时加载,NSCoding - iOS设备

问题描述:

约我救了我的数据的方式的一些信息:我有一个由用户添加和删除视图控制器的阵列(这基本上是一个笔记应用程序和视图控制器是文件夹)。视图控制器有几个应用程序需要保存的动态属性以及其中的notes数组,然后Note对象本身有一些需要保存的属性。当然视图控制器和注释都具有适当的NSCoding东西,这是上视图控制器例如一个: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保存控制器数组 - 它成功地保存了View Controller的所有属性,其属性和所有Notes的属性。下面是在辛格尔顿代码:

- (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; 
    } 
} 

我随后致电多次在文件夹视图控制器保存方法:

[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”和“无法识别的选择发送到实例”是指有一个字符串的地方不应该有be,as associatedCellIsSelected是一个布尔值。但是,如果我只在heightForRow中返回“currentNote.myHeight”,我也会得到与myHeight相同的__NSCF错误,这是一个浮点数。如果我将heightForRow放在一起,除了适当的高度定义之外,一切都可以工作。

顺便说一句,表认为heightForRowAtIndexPath所引用在的loadView所作的笔记阵列AFTER制成并填充。我只是不明白为什么这个错误每隔一段时间就会弹出一次(比如5-10次打开,储蓄,关闭和重新打开应用程序),看似随意 - 我找不到导致此行为的模式。任何指针?

很抱歉的混乱,我是新来的iOS编程,我相信我做了很多事情错在这里。

编辑 - 此外,一旦应用程序崩溃,它保持崩溃每次我打开它(除非我禁用heightForRow),直到我卸载并重新安装时间。

当您看到“无法识别的选择器”错误,并且接收器类型不是您编码的对象类型(在此例中为__NSCFString而不是Note)时,您可能遇到问题,使用已经过早释放,并且其地址空间正被重新用于分配新对象。

修复程序取决于追踪发生额外释放的位置(或保留未发生)。如果您可以显示notes的@property声明,它可能会更清楚地说明情况。

要做的一件事就是从菜单中选择Product-> Analyze并修复它标记的任何东西。它不会抓住所有东西,但它是一个很好的理智检查。

+0

...最简单的调试方法是打开僵尸。 http://*.com/questions/5386160/how-to-enable-nszombie-in-xcode –

+0

那么简单。看了一下后,我发现在一种方法中,我过早地在笔记本被删除之前将一个笔记保存到数据库中,所以当应用程序打开时,它正在寻找不在那里的笔记。谢谢菲利普和杰西! – Zack