2011-09-26 4 views
2

NSCoder이 다음에 디코딩 될 때 여러 객체가 공유하고 인코딩 한 객체를 처리하는 방법이 궁금합니다. 객체의 복사본을 두 개 만들거나 하나의 객체를 디코딩하여 다른 객체간에 공유합니까?NSCoder 및/또는 NSKeyedUnarchiver는 동일한 객체의 여러 디코딩을 어떻게 처리합니까?

다음과 같은 상황에 대한 간단한 예를 제공했습니다.

예 :

  1. 출원은 대리인
  2. 어플리케이션 종료 통지를 받으면
  3. 오브젝트 A와 오브젝트 B 세트 오브젝트 C를 시작한다.
  4. 개체 A와 개체 B 자신과
  5. 응용 프로그램이 종료되고
  6. 객체 A와 객체 B 디코드에게 자신과 모든 개체를 다시 시작 (자신의 대표 포함) 자신의 모든 개체 (포함 인코딩 자신의 대리자)

6 단계 후에 Object A와 Object B는 모두 동일한 디코딩 된 개체를 공유합니까? 아니면 각 개체에 자체 복사본이 있습니까?

답변

6

그들은 그 행동을 변경하기위한 길이로 이동하지 않는 한 동일한 객체에 대한 참조를 공유합니다.

e.e. NSCoding은 (모든 그래프 참여자가 NSCoding을 올바르게 지원하는 한) 완전 순환, 무 지향성, 복잡하게 연결된 객체 그래프를 처리 할 수 ​​있습니다.

인코딩 대리자는 매우 일반적이지 않습니다. 대리자는 일반적으로 보관되지 않은 개체 그래프 에 연결됩니다. 무정부 및 대리인은 보관 된 모델 계층 (IB의 경우 보관 된 뷰 계층 - 사례가 실제로는 XIB 파일의 경우 더 복잡합니다.) 사이의 일종의 관문 역할을합니다. ...하지만 충분히 ...) 및 나머지 앱.

+0

그래, 나는 대개 대리인을 인코딩하지 않을거야. 나는 짧은 순간에 더 좋은 예를 생각할 수 없었다. 나는 내 실제 상황을 사용할 수 있다고 생각하지만 필요한 것보다 더 타이핑을했다. 어쨌든, 고마워! –

+0

걱정할 필요가 없습니다. 단지 확인하고 싶습니다. :) – bbum

0

저는 첫 번째 대답이 완전히 정확하다고 생각하지 않습니다. Apple의 설명서에 따르면 "직렬화는 객체의 값과 계층 구조에서의 위치 만 유지하므로 같은 값 객체에 대한 다중 참조는 직렬화 될 때 여러 객체가 될 수 있습니다".

따라서 여러 개의 NSCoders에서 직렬화 될 때 단일 개체가 직렬화 될 것이라는 보장은 없습니다.

구현이 예제와 비슷하다면 꽤 옳은 것을 생각하지 않을 수도 있습니다. 응용 프로그램의 논리적 구성에 대해 생각해 보면 여러 개체가 동일한 대리인을 공유 할 수 있음을 의미합니다. 하지만 일반적으로 누군가가 NSCoder 프로토콜을 사용하여 대리인을 인코딩/디코딩 할 것으로 기대하지는 않습니다. 일반적으로 대리인이 대리자 인 개체를 인코딩/디코딩 할 것을 기대합니다.

예를 들어 NSTableView를 살펴 보겠습니다. 아마도 사용자는 NSTableView가 표시되는 방식을 구성 할 수 있습니다 (사용자가 열의 크기를 조정하거나 표시 할 열을 선택할 수있는 경우도 있음). 이 정보는 NSCoding 프로토콜을 사용하여 저장하고 복원하려는 유용한 정보입니다. NSTableView에는 대리인도 있습니다.대리자는 MVC 패러다임의 컨트롤러 여야하며 런타임 상태를 유지할 필요가없는 일반 코드이기 때문에 NSCoding을 사용하여 인코딩/디코딩 할 필요가 없습니다.

그래서 init 메소드를 사용하여 대리인/컨트롤러를 만드는 것이 이상적입니다. 사용자가 마지막으로 구성한 방식대로 NSTableView를 구성해야하므로 NSCoding을 사용하여 디스크에서 이전 테이블보기를 가져온 다음 마지막으로 본 것처럼 사용자에게 표시합니다. .

MVC 패러다임의 Model 레이어도 마찬가지라고 생각합니다. 컨트롤러 레이어는 사용자가 응용 프로그램을 사용하여 수행 한 작업과 관련된 모델 객체를 디코딩해야합니다.

컨트롤러 레이어를 모델 또는 인스턴스 레이어에서 인스턴스화하는 것처럼 들립니다. 그것은 실제로 말이되지 않습니다.

+0

공정한 지적이지만, 질문에 대답하지 않습니다. 이것은 아카이버의 행동에 관한 것입니다. 질문에 대한 의견이나 간단한 메모 (예 : bbum의 대답. –

+0

"동일한 ** 값 개체 **에 대한 여러 참조 **로 인해 여러 개체가 직렬화 될 수 있습니다". 그 객체들은 -isEqual :와 -hash가 같았습니다. 그것은 문서에서 명확히해야합니다. – bbum

+0

내 대답은 첫 번째 단락에있었습니다. – Carter

3

이것은 큰 질문이며, 나는 항상 그것에 대해 궁금해했습니다. 그래서, 그것을 시험해보기 위해 작은 테스트 프로그램을 작성했습니다. 네 클래스 : ClassA, ClassB, ClassCMyBaseClass. ClassA, ClassBClassCNSCoding에 부합하며 nameage의 두 가지 속성을 제공합니다. ClassAClassBClassC의 인스턴스에 대한 참조가 포함되어 있다는 점을 제외하면 A, B 및 C 클래스는 동일합니다. ClassAClassBinitwithCoder:encodeWithCoder:을 덮어 쓰고 ClassC의 인스턴스에 대한 참조를 디코딩하고 인코딩합니다. 다음은 최상위 코드의 모습입니다.

ClassA *a = [[ClassA alloc] initWithName:@"Mr. A" age:11]; 
ClassB *b = [[ClassB alloc] initWithName:@"Mrs. B" age:22]; 
ClassC *c = [[ClassC alloc] initWithName:@"Ms. C" age:33]; 

b.c = c; 
a.c = c; 

NSArray *rootObject = @[a, b, c]; 
NSString *const kFilePath = @"/Users/myname/Documents/testarchive"; 
BOOL result = [NSKeyedArchiver archiveRootObject:rootObject toFile:kFilePath]; 
NSLog(@"result = %@", (result) ? @"YES" : @"NO"); 

NSArray *newRootObject = [NSKeyedUnarchiver unarchiveObjectWithFile:kFilePath]; 
NSLog(@"new root object = %@", newRootObject); 

개체가 완벽하게 직렬화 및 비 직렬화됩니다. 또한 비 직렬화 후 a.cb.cClassC의 동일한 인스턴스를 가리 킵니다. 즉, 해당 객체 포인터의 주소가 동일합니다. 객체가 이전에 부호화 대상 isEqualTo: 부호화되는 경우 NSKeyedArchiverencodeObject:forKey: 내의 명백하게

는 시험 보러 수행되고,이 경우, 기준 대신에 완전한 객체에 저장된다. 그 반대는 NSKeyedUnarchiverdecodeObject:forKey:에서 발생해야합니다. 아주 멋지다!

관련 문제