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并修复它标记的任何东西。它不会抓住所有东西,但它是一个很好的理智检查。
...最简单的调试方法是打开僵尸。 http://stackoverflow.com/questions/5386160/how-to-enable-nszombie-in-xcode –
那么简单。看了一下后,我发现在一种方法中,我过早地在笔记本被删除之前将一个笔记保存到数据库中,所以当应用程序打开时,它正在寻找不在那里的笔记。谢谢菲利普和杰西! – Zack