programing

임시 NSManaged Object 인스턴스를 처리하는 방법은 무엇입니까?

codeshow 2023. 9. 19. 21:30
반응형

임시 NSManaged Object 인스턴스를 처리하는 방법은 무엇입니까?

나는 창조할 필요가 있습니다.NSManagedObject인스턴스들은 그것들로 무언가를 한 다음 그것들을 버리거나 sqlite db에 저장합니다.의 인스턴스를 수 입니다.NSManagedObject한과 이 없는NSManagedObjectContext그리고 이것은 제가 제 db에 있는 객체들 중 일부가 필요하지 않다고 결정한 후에 어떻게든 정리해야 한다는 것을 의미합니다.

에 대응하기 거기에 를 하고 있습니다.assignObject:toPersistentStore.이제 어떻게 하면 이러한 임시 객체가 공통에서 양쪽 저장 컨텍스트로 가져오는 데이터에 도달하지 않도록 할 수 있습니까?아니면 그런 작업을 위해 별도의 컨텍스트를 만들어야 합니까?


업데이트:

이제 인메모리 스토어를 위한 별도의 컨텍스트를 만들까 생각 중입니다.개체를 한 컨텍스트에서 다른 컨텍스트로 이동하려면 어떻게 해야 합니까?[context insertObject:]을(를) 사용하기만 하면 됩니까?이 설정에서 잘 작동합니까?객체의 그래프에서 하나의 객체를 삽입하면 전체 그래프도 컨텍스트에 삽입됩니까?

참고: 이 답변은 매우 오래된 답변입니다.자세한 내용은 댓글을 참조하십시오.그 이후로 권장 사항이 변경되었으며 더 이상 연관되지 않은 사용을 권장하지 않습니다.NSManagedObject예를 들면 은 임시 저의 현재 권장사항은 임시 자녀를 사용하는 것입니다를 사용하는 입니다.NSManagedObjectContext들면

원답

은 를 입니다.NSManagedObjects가 인스턴스NSManagedObjectContext.

NSEntityDescription *entity = [NSEntityDescription entityForName:@"MyEntity" inManagedObjectContext:myMOC];
NSManagedObject *unassociatedObject = [[NSManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:nil];

저장하고 싶을 때:

[myMOC insertObject:unassociatedObject];
NSError *error = nil;
if (![myMoc save:&error]) {
  //Respond to the error
}

iOS5는 마이크 웰러의 답변에 대한 보다 간단한 대안을 제공합니다.대신 하위 NSManagedObjectContext를 사용합니다.NS Notification Center를 통해 트램펄린을 할 필요가 없습니다.

하위 컨텍스트를 만드는 방법:

NSManagedObjectContext *childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
childContext.parentContext = myMangedObjectContext;

그런 다음 하위 컨텍스트를 사용하여 개체를 만듭니다.

NSManagedObject *o = [NSEntityDescription insertNewObjectForEntityForName:@"MyObject" inManagedObjectContext:childContext];

변경 사항은 자식 컨텍스트가 저장된 경우에만 적용됩니다.따라서 변경 내용을 삭제하려면 저장하지 마십시오.

아직도 인간관계에는 한계가 있습니다.즉, 다른 컨텍스트에서 개체에 대한 관계를 만들 수 없습니다.이 사용 개체를 이동하려면ID, 하위 컨텍스트에서 개체를 가져옵니다.예를 들면

NSManagedObjectID *mid = [myManagedObject objectID];
MyManagedObject *mySafeManagedObject = [childContext objectWithID:mid];
object.relationship=mySafeManagedObject;

참고로 자식 컨텍스트를 저장하면 변경 내용이 부모 컨텍스트에 적용됩니다.상위 컨텍스트를 저장하면 변경 사항이 유지됩니다.

자세한 설명은 wwdc 2012 세션 214를 참조하십시오.

이러한 작업을 수행하는 올바른 방법은 새로운 관리 개체 컨텍스트를 사용하는 것입니다.동일한 영구 저장소를 사용하여 관리 개체 컨텍스트를 생성합니다.

NSManagedObjectContext *tempContext = [[[NSManagedObjectContext alloc] init] autorelease];
[tempContext setPersistentStore:[originalContext persistentStore]];

그런 다음 새로운 개체를 추가하고 변형시키는 등의 작업을 수행합니다.

저장 시점이 되면 tempContext에서 [tempContext save:...]를 호출하고 저장 알림을 처리하여 원래 컨텍스트에 병합해야 합니다.개체를 삭제하려면 이 임시 컨텍스트를 해제하고 잊어 버리면 됩니다.

따라서 임시 컨텍스트를 저장할 때 변경 사항이 저장소에 지속되고 이러한 변경 사항을 기본 컨텍스트로 다시 가져오기만 하면 됩니다.

/* Called when the temp context is saved */
- (void)tempContextSaved:(NSNotification *)notification {
    /* Merge the changes into the original managed object context */
    [originalContext mergeChangesFromContextDidSaveNotification:notification];
}

// Here's where we do the save itself

// Add the notification handler
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(tempContextSaved:)
                                             name:NSManagedObjectContextDidSaveNotification
                                           object:tempContext];

// Save
[tempContext save:NULL];
// Remove the handler again
[[NSNotificationCenter defaultCenter] removeObserver:self
                                                name:NSManagedObjectContextDidSaveNotification
                                              object:tempContext];

이는 다중 스레드 핵심 데이터 작업을 처리하는 방식이기도 합니다.스레드당 하나의 컨텍스트.

(관계 등을 추가하기 위해) 이 임시 컨텍스트에서 기존 개체에 액세스해야 하는 경우 개체의 ID를 사용하여 다음과 같은 새 인스턴스를 가져와야 합니다.

NSManagedObject *objectInOriginalContext = ...;
NSManagedObject *objectInTemporaryContext = [tempContext objectWithID:[objectInOriginalContext objectID]];

만약 당신이 사용하려고 한다면.NSManagedObject잘못된 맥락에서 저장하는 동안 예외가 발생합니다.

nil 컨텍스트에서 임시 객체를 만드는 것은 컨텍스트가 != nil!인 객체와 실제로 관계를 맺으려고 할 때까지 잘 작동합니다.

괜찮으시겠어요?

하고 있는 입니까입니까?NSManagedObjectContext을 위한 것입니다.

From Core Data Programming Guide: Core Data Basics

관리되는 객체 컨텍스트는 지능형 스크래치 패드라고 생각할 수 있습니다.영구 저장소에서 개체를 가져올 때 임시 복사본을 스크래치 패드에 가져와 개체 그래프(또는 개체 그래프 모음)를 형성합니다.그런 다음 원하는 대로 개체를 수정할 수 있습니다.그러나 변경 사항을 실제로 저장하지 않는 한 영구 저장소는 변경되지 않습니다.

핵심 데이터 프로그래밍 가이드: 관리 개체 검증

이는 또한 "스크래치 패드"를 나타내는 관리 개체 컨텍스트의 개념을 뒷받침합니다. 일반적으로 관리 개체를 스크래치 패드로 가져와 원하는 대로 편집한 후 최종적으로 변경을 실행하거나 폐기할 수 있습니다.

NSManagedObjectContexts는 경량으로 설계되었습니다.당신은 그것들을 마음대로 만들고 버릴 수 있습니다 - 그것은 지속적인 상점 조정자이고 의존성이 "무거운" 것입니다.단일 영구 저장소 코디네이터에는 여러 가지 컨텍스트가 연결될 수 있습니다.오래된 쓰레드 구속 모델에서는 각 컨텍스트에 동일한 영구 저장소 코디네이터를 설정할 수 있습니다.오늘날 이는 중첩된 컨텍스트를 영구 저장소 코디네이터와 연관된 루트 컨텍스트에 연결하는 것을 의미합니다.

컨텍스트를 만들고 해당 컨텍스트 내에서 관리 개체를 만들고 수정합니다.이러한 변경사항을 지속적으로 유지하고 변경사항을 전달하려면 컨텍스트를 저장합니다.그렇지 않으면 버립니다.

관리 개체 생성 시도 중에 관리 개체와 독립적으로NSManagedObjectContext문제를 요구하는 겁니다핵심 데이터는 궁극적으로 객체 그래프의 변경 추적 메커니즘이라는 점을 기억해야 합니다.이 때문에 관리 개체는 실제로 관리 개체 컨텍스트의 일부입니다.컨텍스트는 수명 주기를 관찰하며 컨텍스트가 없으면 모든 관리 개체 기능이 올바르게 작동하지 않습니다.

임시 개체를 사용하는 경우에 따라 위의 권장 사항에 대한 몇 가지 주의 사항이 있습니다.저의 활용 사례는 임시 객체를 만들어 보기에 바인딩하고 싶습니다.사용자가 이 개체를 저장하도록 선택하면 기존 개체에 대한 관계를 설정하고 저장합니다.이 값을 유지할 임시 개체를 만들지 않기 위해 이 작업을 수행합니다.(네, 사용자가 저장할 때까지 기다렸다가 보기 내용을 잡을 수 있지만, 이 보기를 테이블 안에 넣으니 논리가 덜 우아합니다.)

임시 개체에 대한 옵션은 다음과 같습니다.

1) (Preferred) 하위 컨텍스트에서 임시 개체를 만듭니다.개체를 UI에 바인딩하고 있고 개체 액세스자가 하위 컨텍스트에서 호출되는지 확인할 수 없기 때문에 작동하지 않습니다.( 달리 명시된 문서를 찾지 못했기 때문에 추정해야 합니다.)

2) 개체 컨텍스트가 0인 임시 개체를 만듭니다.이는 작동하지 않으며 데이터 손실/파손을 초래합니다.

내 솔루션:개체 컨텍스트가 0인 임시 개체를 생성하여 해결했지만 개체를 #2로 삽입하는 대신 개체를 저장하면 해당 속성을 모두 기본 컨텍스트에서 생성하는 새 개체로 복사합니다.NSManagedObject 하위 클래스에서 clone이라는 지원 메서드를 만들었습니다.Into: 속성 및 관계를 모든 개체에 대해 쉽게 복사할 수 있습니다.

저는 스위프트를 위한 이 답변을 이 질문에 대한 빠른 방향 전환을 위한 모든 유사한 질문으로 다시 씁니다.

다음 코드를 사용하여 ManagedContext 없이 개체를 선언할 수 있습니다.

let entity = NSEntityDescription.entity(forEntityName: "EntityName", in: myContext)
let unassociatedObject = NSManagedObject.init(entity: entity!, insertInto: nil)

나중에 개체를 저장하려면 컨텍스트에 개체를 삽입하여 저장할 수 있습니다.

myContext.insert(unassociatedObject)
// Saving the object
do {
    try self.stack.saveContext()
    } catch {
        print("save unsuccessful")
    }
}

제게는 마커스의 대답이 통하지 않았습니다.제게 도움이 된 것은 다음과 같습니다.

NSEntityDescription entityForName:@"MyEntity" inManagedObjectContext:myMOC];
NSManagedObject *unassociatedObject = [[NSManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:nil];

저장하기로 결정한 경우:

[myMOC insertObject:unassociatedObjet];
NSError *error = nil;
[myMoc save:&error];
//Check the error!

우리는 또한 그것을 풀어주는 것을 잊지 말아야 합니다.

[unassociatedObject release]

언급URL : https://stackoverflow.com/questions/3256195/how-to-deal-with-temporary-nsmanagedobject-instances

반응형