2012-11-19 2 views
6

이 두 호출 간의 문서화 된 차이점을 알고 있습니다. 그렇지만 누구나 내가 알아 차린 다음과 같은 관찰 된 동작의 이유를 알고 있습니까?설명되지 않은 objectWithID : existingObjectWithID 간의 동작 차이 :

[childContext objectWithID : objectID]를 사용하는 경우 childContext를 사용하여 편집, 삽입 및 삭제 한 parentContext 및 임시 childContext가있는 경우; 부모 컨텍스트에있는 알려진 기존 관리 객체를 검색 할 때 가끔 해고 될 때 오류가 발생하고 예외가 발생하는 오류가있는 객체를 제공합니다. 나는 objectWithID를 이해합니다 : 주어진 objectID에 대한 실제 managedObject가 있는지 여부에 관계없이, 의도적으로 오류 상태의 객체를 반환합니다. 그러나 객체가 부모 컨텍스트에 실제로 존재하는 경우, 속성 중 하나에 액세스 할 때 아무 문제없이 객체가 항상 부모 컨텍스트에서 성공적으로 검색됩니다 (예 : 오류 발생). [childContext existingObjectWithID : objectID]를 사용하는 경우; 나는 그것이 실제로 항상 성공한다는 것을 안다.

레코드의 경우 하위 컨텍스트에서 캐싱을 해제했으며 [childContext resetContext]를 호출 한 후 이와 동일한 문제가 발생합니다. 따라서 부모 컨텍스트와 일치하지 않는 오래된 캐싱 된 데이터의 인공물이 아닙니다.

설명서만으로는이 동작을 설명하기에는 부족한 것처럼 보입니다. 나는 물론 그것을 경험하고 단지 "항상 existingObjectWithID를 사용한다는 것을 알았습니다 : 객체 ID를 자식 편집 컨텍스트 블록으로 전달할 때 블록을 수행한다는 것을 알았습니다."라고 말하지만 불안해하고 정확히 무슨 일이 일어나고 있는지 이해하고 싶습니다. 적어도 하나는 다른 것보다 성능에 미치는 영향이 있는지 이해할 수있을뿐만 아니라 제약 조건이 무엇인지 이해할 수 있으므로 불필요하게 코드에서 구현 한 다음 그것을 고치기위한 잘못되었거나 비효율적 인 호출).

답변

1

내 자신의 코드에서이 동작을 보았습니다. (스택 추적은 화성에서 가져 왔으며 영원히 문제의 원인을 추적했습니다.) 내 솔루션은 동일했습니다 (objectWithID 사용에서 이동 : 하위 existingObjectWithID를 사용할 컨텍스트 :).

필자의 경우, 상위 컨텍스트에서 개체를 만들고 즉시 영구 개체 ID를 얻고 UIManagedDocument의 updateChangeCount : UIDocumentChangeDone을 ​​사용하여 저장을 요청하면 나중에 어느 시점에서 저장 일정이 잡히게됩니다 . 나는이 점이 토론의 열쇠라고 생각한다.

그런 다음 네트워크 호출을 수행하여 새로 생성 된 개체와 관련된 XML 데이터를 가져 와서 해당 데이터를 구문 분석하여 핵심 데이터로 가져옵니다. 이 배경 스레드에서 발생하고 스레드 제한된 자식 가져 오기 컨텍스트를 사용하는 스레드에 개체 ID를 전달합니다.

iOS5에서 objectWithID :를 사용하여 작업자 스레드에서 새 객체를 가져 오기 컨텍스트에 폴트 (fault)시킵니다. 잘 작동했지만 문제가 없습니다.

iOS6에서는 기묘한 스택 추적으로 실패하기 시작했으며 유일한 해결책은 existingObjectWithID :로 옮기는 것이 었습니다. 테스트를 통해이 변경 사항을 적용한 견고한 솔루션 인 것으로 보입니다.

당신처럼, 나는 왜 이것이 작동하는지에 대한 확실한 진술을 찾으려고했지만, 그렇게하지 못했습니다. 그러나, 나는 내 코드가 보여주는 패턴과 내가 본 스택 추적이 어쩌면 일어날지를 설명한다고 생각한다. 영구 저장소에서 데이터를 가져 오는 동안 항상 충돌이 발생하고있었습니다. 나는 iOS5에서 자식 스레드가 실행되기 전에 UIManagedDocument를 통해 요청한 save가 발생했기 때문에 objectWithID :를 호출하기 전에 새 객체가 지속되었다고 생각한다. 내 충돌 로그에서 iOS6에 해당하지 않는 것으로 나타납니다. 객체가 영구 저장소에 저장되기 전에 스레드가 실행되므로 아직 자식 컨텍스트로 가져올 수 없습니다.필자의 가정은 existingObjectWithID :는 페치를 시도하기 전에 보류중인 SQL 입출력이 수행되도록 보장하므로 페치가 작업자 스레드에서 발생하면 영구 저장소가 일관성을 유지합니다. 이 문제를 지원하는 데 결정적인 것을 찾을 수 없었지만 광범위한 테스트를 통해 그러한 현상이 뒷받침되는 것으로 보입니다.

+1

감사합니다. Allan. 나는 지금 그것을 단지 무시하고 있으며, 다른 누군가도 (성공적으로) 그것을 무시하고 있음을 아는 것은 도움이된다. 나는 지금 내 코딩과 함께 매우 편안한 장소에 있으며, "알지 못함"또는 "이해하지 못함"문제는 내가 처음 시작했을 때와 같은 것을 너무 많이 상기시킨다. 내 코드가 괜찮 으면 항상 걱정한다. 또는 나에게 물을 줘도. 그러나 길의 아래에서 그 이상! – TheBasicMind

+0

설명과 해결책을 가져 주셔서 감사합니다. 나는 UIManagedDocument를 사용하여이 문제도 다루었 다. existingObjectWithID로 전환 한 후 내 첫 번째 테스트 : 오류 : 유망했다. –

0

objectWithID을 사용하여 "충돌 개체"를 얻기 전에 existingObjectWithID을 사용하여 "기존 개체"를 가져 오면 두 개체가 동일하게됩니다.

"충돌 객체"의 속성에 액세스하면 응용 프로그램을 반대로 다른 방법으로 충돌이 발생합니다. 이 경우 객체는 동일하지 않습니다. "충돌 개체"에는 임시 ObjectID가 있습니다.

1

영업과 같은 문제를 갖는, 내가 생각하는 동안 예외가 애플의 문서에서

If the object is not registered in the context, it may be fetched or returned as a fault. This method always returns an object. The data in the persistent store represented by objectID is assumed to exist—if it does not, the returned object throws an exception when you access any property (that is, when the fault is fired). The benefit of this behavior is that it allows you to create and use faults, then create the underlying data later or in a separate context.

에 따라 디자인입니다 - 즉은, 데이터는 그건 아직 영구 저장소에 아닙니다 부모 컨텍스트에 앉아서 - 그것은 부모 컨텍스트에서 단순히 실현 된 객체를 얻을 수 없다는 것이 여전히 이상하게 보입니다. 객체가 채워지려면 왜 퍼시 스턴트 스토어가 그것에 대해 알아야합니까?

관련 문제