2012-06-05 4 views
1

내 데이터를 저장하는 방법에 대한 일부 정보 : 사용자가 추가하거나 삭제 한 뷰 컨트롤러 배열이 있습니다 (기본적으로 앱을 사용하는 노트이며 View Controller 폴더입니다. 뷰 컨트롤러에는 앱이 저장해야하는 몇 가지 동적 속성과 그 안에 메모 배열이 포함되어 있으며, Note 개체 자체에는 몇 가지 속성을 저장해야합니다.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; } 

컨트롤러의 배열은 싱글 톤 클래스에 속하는 : 물론보기 컨트롤러 및 메모 모두 적절한 NSCoding 물건을 가지고, 이것은 예를 들어보기 컨트롤러의 하나입니다. NSCoding은 단순한 것으로 간주되지만 꽤 혼란 스럽지만, 지금까지는 Singleton에게 Controllers 배열을 저장하는 것으로 성공했습니다. ViewStation의 모든 포함 된 속성을 저장하고 (성공적으로) 그들의 속성과 모든 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]; 

을 그리고 무작위로 충돌을 얻을 때까지이 잘 여러 번 작동 여기에 싱글의 코드는 앱이로드 될 때 바로.

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

나는 다음과 같은 오류 얻을

: 범인은 heightForRowAtIndexPath이다 나는 "__NSCFString"와 "인식 할 수없는 선택기 인스턴스로 전송"을 이해

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: 

문자열 어딘가에 있다는 것을 의미 없다해야 be, as associatedCellIsSelected는 bool입니다. 그러나 heightForRow에서 "currentNote.myHeight"만 반환하면 float 인 myHeight와 동일한 __NSCF 오류가 발생합니다. heightForRow를 모두 함께 사용하면 적절한 높이 정의를 제외한 모든 것이 작동합니다.

현재 메모 배열이 만들어지고 채워진 후 loadView에서 heightForRowAtIndexPath가 참조하는 테이블보기가 만들어집니다. 난이 오류가 갑자기 (5-10 열, 저축, 폐쇄 및 응용 프로그램 다시 열 때마다) 갑자기 나타나는 이유를 이해하지 못합니다. 겉보기에 임의로 -이 동작을 일으키는 패턴을 찾을 수 없습니다. 어떤 포인터?

엉망으로 죄송합니다. iOS 프로그래밍을 처음 접했고 여기서 많은 실수를 저지르고 있습니다.

편집 - 또한 응용 프로그램이 손상되면 다시 제거 할 때까지 (heightForRow를 비활성화하지 않는 한) 응용 프로그램을 다시 열 때마다 응용 프로그램이 계속 중단됩니다.

답변

1

"인식 할 수없는 선택기"오류가 표시되고 수신기 유형이 코딩 한 개체 종류 (이 경우 Note 대신 __NSCFString)가 아닌 경우 의도 한 개체에 문제가있는 것입니다 사용이 조기에 해제되었고 주소 공간이 새로운 객체를 할당하기 위해 재사용되고 있습니다.

수정 사항은 추가 릴리스가 발생한 위치를 추적하거나 유지하지 않는 경우에 따라 달라집니다. notes에 대한 @property 선언을 표시 할 수 있다면 더 많은 상황을 알 수 있습니다.

빠른 작업 중 하나는 메뉴에서 Product-> Analyze를 선택하고 플래그가있는 것을 수정하는 것입니다. 모든 것을 잡을 수는 없지만 시작하는 것은 좋은 정신 체크입니다.

+0

... 그리고 이것을 디버그하는 가장 쉬운 방법은 좀비를 켜는 것입니다. http://stackoverflow.com/questions/5386160/how-to-enable-nszombie-in-xcode –

+0

간단합니다. 한 가지 방법을 사용하여 삭제 된 직전에 데이터베이스에 메모를 저장하는 중 한 방법을 발견했습니다. 따라서 앱이 다시 열리면 거기에없는 메모를 찾고있었습니다. 감사 필립과 제시! – Zack