2012-07-03 4 views
0

특정 기능을 구현하는 가장 좋은 방법을 알고 싶습니다. 사용자가 NSManagedObject MessageObject을 생성하는 메시지 작성자보기가 있습니다. 또한 글로벌 인스턴스가 초기화 된 클래스 ObjectHelper이 있습니다.하나의보기에서 NSManagedObject를 만들고 다른보기에 저장하십시오.

나는 배경 (비공개 대기열)이 NSManagedObjectContext이고, 사용자가 작성보기를 입력하면 바로 MessageObject을 생성합니다. 여기 캐치는 ObjectHelper (하지 ComposerViewController)이이 새로운 개체의 소유자입니다 - 그것은 강한 참조 속성 변수가 있습니다 내 ComposeViewController 다시, 그리고

ObjectHelper.h:

@property(nonatomic, strong) MessageObject *newObject; 

을 30 초마다 객체를 디스크에 저장하는 타이머를 설정합니다 (자동 저장과 같은 초안을 저장합니다. 사용자가 어떻게 든 중단되거나 응용 프로그램이 충돌하거나 데이터가 지워지지 않을 수 있기 때문에).

그런 다음 사용자가 저장 버튼을 누르면 주 스레드에서 가능한 한 작게 작업하여 모달보기 애니메이션이 부드럽게 처리되고 기능이 주보기 컨트롤러로 빨리 돌아갑니다. 그래서 내가 할 것은, 메시지 객체의 값을 가진 NSDictionary를 만들 업데이트가 이미 사전의 값으로 작성보기의 시작 부분에서 만든 newObject 인스턴스이 무엇 [globalObjectHelperInstance updateNewObjectInstanceWithDictionary:]

를 호출하고있다 그것을 백그라운드 스레드에서 수행합니다.

그런 다음 모달을 닫습니다.

나는 (당신이 무엇을 할 수있는 답변을 바랍니다) 여기에 몇 가지 질문이 있습니다

  1. 기능을 절약보다는 ObjectHelper의 속성 인스턴스를 생성하는 "초안"을 구현하는 더 나은 방법이 있나요? (ComposeController 이외의 외부 클래스에서 속성 인스턴스를 만드는 이유는 배경 작업이 개체에서 수행되는 동안보기 컨트롤러가 닫히기 때문입니다. 그래서 인스턴스 변수를 만들면 메모리에서 사라질 것 같습니다.)

  2. 속성 참조가 약하거나 강해야합니까? NSManagedObjectContext은이 객체에 보류중인 저장되지 않은 변경 사항이없는 한 해당 객체를 유지할 수 없다는 것을 알고 있습니다. 저장하기 전에 [globalObjectHelperInstance updateNewObjectInstanceWithDictionary:]에서 [backgroundMOC obtainPermanentIDsForObjects:self.newObject error:&error]를 호출하는 몇 가지 이유를 들어

  3. 는 EXC_BAD_ACCESS 충돌이 발생합니다. 나는 이것이 내 상황에서 기억을 관리하는 방식과 관련이 있다고 생각한다. 임시 저장

답변

1
  1. 귀하의 방법은 나에게 아주 좋은 것 같다.

    또 다른 옵션은 개체에 속성 참조를 유지하지 않고 일부 키로 초안 개체를 가져 와서 업데이트 한 다음 다시 저장하는 것입니다. 이것은 당신이 무언가를 거의 저장하지 않거나 매우 큰 것을 가지고있는 경우에 의미가있을 수 있지만 현재의 접근 방식은 훨씬 더 적합합니다.

  2. 참조가 강해야합니다.당신은 당신이 그것을 업데이트하기를 원할 때 항상 존재하기를 원하며 당신은 그것의 존재를 요구한다. 참조가 약한 경우 개체가 삭제 될 수 있습니다. 디스크상의 데이터베이스에있는 객체는 남아 있지만 인 - 메모리 표현은 제거 될 것이고, 그것을 원하지 않을 것이다.

    이것이 메모리 과다 사용이나 누출을 일으킬 수있는 이유는 없습니다. 단지 하나의 객체 일 뿐이며 순환 참조를 두려워하지 않습니다.

  3. 크래시와 관련하여 처음에는 주 스레드의 MOC에서 ID를 얻어 백그라운드 MOC에서 사용해야합니다. 또한 NSManagedObject보다는 스레드 경계 사이에 NSDictionary을 전송하는 것이 더 쉽기 때문에 초안을 항상 배경 MOC에 보관해야합니다.

    updateNewObjectInstanceWithDictionary:의 코드는 백그라운드 큐의 GCD 블록을 호출하고 사전에 저장하여 전달합니다.

+0

답장을 보내 주셔서 감사합니다. 포인트 3의 경우, 하위 ID를 얻기 전에 주 컨텍스트의 하위 인 백그라운드 컨텍스트에 먼저 저장해야 할 필요가 없습니까? 배경에 먼저 저장하지 않으면 주요 컨텍스트가이 새 개체에 대해 알지 못하기 때문에 맞습니까? 그리고 내 목표를 배경 MOC에 항상 유지하는 것과 마찬가지로, 내가하는 일이 아닌가? – Snowman

+0

백그라운드 MOC에서이 드래프트 객체를 생성하거나 가져 오는 경우, 예, 그렇게하는 것입니다. :). 그렇다면 내 대답은 그 시점과 관련이 없으며 나는 당신의 추락에 대해 더 이상 논평 할 수 없다고 생각합니다. 나는 항상 스레드 경계를 통해 데이터를 이동하는 것을 피하고, 주 스레드에 작은 객체를 유지하고 백그라운드에서만 동기화를 남겨 둡니다. – coverback

+0

충돌에 대해서는'[backgroundMOC obtainPermanentIDsForObjects : self.newObject error : & error]'를'[backgroundMOC obtainPermanentIDsForObjects : backgroundMOC.managedObjects.allObjects error : & error]'로 대체하면 충돌이 없어집니다. 이것이 무슨 뜻일까요? – Snowman

관련 문제