3

Archiver의 버전을 사용 중이며 문제가 발생했습니다. 내 프로젝트 클래스의 이전 버전에서 NSKeyedArchiver로 유지 된 객체를 이전하는 방법은 무엇입니까?

, 도전는 욕망이 새로운 2를 추가하여 도전 객체를 변경하는 응용 프로그램의 버전 1.1,

//v1.0 
@interface Challenge : NSObject<NSCoding> 
{ 
    ... 
    @property (nonatomic,strong) NSString *challengeId; 
    @property (nonatomic,strong) NSString *title; 
    @property (nonatomic) BOOL isCompleted; 
    ... 
} 

이제 디스크에 연재 @properties. 아카이브가 도전 개체를 해독하려고 시도 할 때 두 개의 새로운 속성이 존재하기 때문에

//v1.1 
@interface Challenge : NSObject<NSCoding> 
{ 
    ... 
    @property (nonatomic,strong) NSString *challengeId; 
    @property (nonatomic,strong) NSString *title; 
    @property (nonatomic) BOOL isCompleted; 
    ... 
    @property (nonatomic) BOOL isActive; 
    @property (nonatomic) NSInteger completeCount; 
} 

내 문제는,이 (예 도전 버전 1.1은 도전을 위해 복사하거나 ALLOC 패턴과 일치하지 않는 V1 .0), 예외가 throw됩니다.

본질적으로 NSEncoding 개체를 마이그레이션하여 비슷한 시나리오를 경험 한 사람이 있었고이 기술을 극복하기 위해 어떤 기술을 사용 했습니까?

옵션은 내가 지금까지 오브젝트 트리에서 도전 위의 슈퍼 클래스를 삽입하려고 시도했습니다

을 고려했지만이 기능을 가져올 수 없습니다.

또한 이전 버전의 지속성 문제를 해독하고 새로운 유형의 객체를 유지하는 릴리스 v1.1의 두 단계 마이그레이션을 고려했습니다. NewChallenge v1.2 준비 - 복잡한 (나 단지 두 개의 속성을 추가하려는 고려).

나는 Challenge를 확장하고 속성이 서브 클래스에 존재한다고 생각했지만, 이것은 Challenge 개체를 볼 것으로 예상되는 많은 코드를 변경하는 것을 의미합니다.

어떤 통찰력이라도 대단히 감사하겠습니다.

답변

2

많은 감사 마이크 메이요 (@greenisus) 무슨 일이 있었는지에 대한 단서를위한 아카이브의 원래 저자 ...

그것은 디코딩하는 동안이의 존재를 확인하는 것이 가능하다는 것을 밝혀에 주어진 키. Archiver 프로젝트는 아래 함수를 사용하여 객체를 해독합니다. 그래서 존재하지 않는 키를 해독하려고 시도 할 수있는 시점에서, 코더가 상기 키에 대해 알고 있는지를 체크한다 .- 계속 절이있는 for 루프의 반복을 건너 뛰지 않는다면 체크한다. 내 경우

- (void) autoDecode:(NSCoder *)coder 
{ 
    NSDictionary *properties = [self properties]; 

    for (NSString *key in properties) 
    { 
     if (![coder containsValueForKey:key]) { 
      continue; 
     } 

     NSString *capitalizedKey = [key stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:[[key substringToIndex:1] capitalizedString]]; 
     NSString *selectorString = [NSString stringWithFormat:@"set%@:", capitalizedKey]; 
     SEL selector = NSSelectorFromString(selectorString); 
     NSMethodSignature *signature = [self methodSignatureForSelector:selector]; 

     if (!signature) { 
      continue; 
     } 

     ... 

는 인코딩 된 객체는 해시 및 설명, 두 번째 계속 절에 따라서 요구 사항을 디코딩을 시도 충돌을 일으켰습니다.