2012-06-05 32 views
1

約我救了我的數據的方式的一些信息:我有一個由用戶添加和刪除視圖控制器的陣列(這基本上是一個筆記應用程序和視圖控制器是文件夾)。視圖控制器有幾個應用程序需要保存的動態屬性以及其中的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),直到我卸載並重新安裝時間。

回答

1

當您看到「無法識別的選擇器」錯誤,並且接收器類型不是您編碼的對象類型(在此例中爲__NSCFString而不是Note)時,您可能遇到問題,使用已經過早釋放,並且其地址空間正被重新用於分配新對象。

修復程序取決於追蹤發生額外釋放的位置(或保留未發生)。如果您可以顯示notes的@property聲明,它可能會更清楚地說明情況。

要做的一件事就是從菜單中選擇Product-> Analyze並修復它標記的任何東西。它不會抓住所有東西,但它是一個很好的理智檢查。

+0

...最簡單的調試方法是打開殭屍。 http://stackoverflow.com/questions/5386160/how-to-enable-nszombie-in-xcode –

+0

那麼簡單。看了一下後,我發現在一種方法中,我過早地在筆記本被刪除之前將一個筆記保存到數據庫中,所以當應用程序打開時,它正在尋找不在那裏的筆記。謝謝菲利普和傑西! – Zack