2014-11-14 6 views
3

이해할 수없는 문제가 있습니다.사용자 정의 다 대 관계 액세서 삭제 규칙을 실행할 때 호출되지 않는 메소드

나는 Collection과 CD가있는 간단한 코어 데이터 모델을 가지고 있습니다. 모든 CD를 여러 컬렉션에 추가 할 수 있으므로이 작업을 가능하게하는 중간 개체를 추가했습니다. (편집 : 이것은 내 DataModel이의 단순화 중간 개체가 컬렉션을 중첩 컬렉션을 위해 필요합니다.)이 CD는 그것을 다음과 같습니다 컬렉션에 추가됩니다 그래서

: 은 (IM은 중간 오브젝트가)

|==========|   |==========|   |==========| 
|   |   |   |   |   | 
|Collection|=========| IM  |=========| CD | 
|   |   |   |   |   | 
|==========|   |==========|   |==========| 

사용자가 CD를 삭제하면 IM 개체가 계단식으로 삭제되고 IM 개체 삭제시 채워지는 컬렉션 속성이 삭제되도록 삭제 규칙을 설정했습니다. 내가 원했던 것처럼 행동하고있다. 데이터베이스에 남은 부분이 없습니다.

하지만 이상한 점은 Collection에서 IM을 제거하기위한 사용자 정의 다 대 관계 액세스 접근 자 메서드를 재정의하면 아무 일도 일어나지 않는다는 것입니다.

저는 Apple에서 제공하는 Core Data Programming Guide를 사용하고 있습니다. 제거 여러 개체에 대한

- (void)removeEmployeesObject:(Employee *)value 
    { 
     NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1]; 
     [self willChangeValueForKey:@"employees" 
      withSetMutation:NSKeyValueMinusSetMutation 
      usingObjects:changedObjects]; 
     [[self primitiveEmployees] removeObject:value]; 
     [self didChangeValueForKey:@"employees" 
      withSetMutation:NSKeyValueMinusSetMutation 
      usingObjects:changedObjects]; 
} 

: 단일 객체의 경우 the link

- (void)removeEmployees:(NSSet *)value 
    { 
     [self willChangeValueForKey:@"employees" 
      withSetMutation:NSKeyValueMinusSetMutation 
      usingObjects:value]; 
     [[self primitiveEmployees] minusSet:value]; 
     [self didChangeValueForKey:@"employees" 
      withSetMutation:NSKeyValueMinusSetMutation 
      usingObjects:value]; 
} 

(PDF 파일에서 가져온, 그들은 여기에 - 많은 관계로 직원을 사용) 그러나 삭제 규칙이 실행될 때 이러한 메소드는 호출되지 않습니다!

내 질문 : IM 개체가 계단식으로 삭제되었지만 이러한 방법은 사용되지 않습니다. 핵심 데이터가 수행하는 삭제 작업을 어떻게 검색합니까?

다른 방법이 있습니까?

변경된 모든 Collection에 "dirtyFlag"를 설정하고 싶기 때문에 이것을 알고 싶습니다. 그래서 그 객체에 대해 몇 가지 사항을 업데이트 할 수 있습니다. (다른 속성은 여기에서 설명하지 않습니다)

(개체의 KVO는 쓸모 없게됩니다. 전체 데이터베이스를 관찰 할 수 없습니까? 아니면이 개체의 Collection 개체 KVO 자체입니까?)

누군가 나를 도울 수 있기를 바랍니다.

답변

3

또는 -prepareForDeletion을 IM managedObject 하위 클래스에 구현할 수 있습니다.
-prepareForDeletion은 managedObjectContext에서 삭제되기 바로 전에 managedObject에서 핵심 데이터에 의해 자동으로 호출됩니다.

-prepareForDeletion을 호출하면 모든 관계를 계속 사용할 수 있으므로 -willDeleteIntermediateObject: 메시지를 포함하는 모든 컬렉션에 self을 매개 변수로 전달할 수 있습니다.

그런 다음 -[Collection willDeleteIntermediateObject:]을 구현하여 마지막으로 포함 된 IM 개체인지 확인하고, 포함 된 경우 해당 메시지를 managedObjectContext에서 삭제할 수 있습니다.

// IM.m 
- (void)prepareForDeletion { 
    [super prepareForDeletion]; 

    for (Collection *collection in self.collections) { 
     [collection willDeleteIntermediateObject:self]; 
    } 
} 

// Collection.m 
- (void)willDeleteIntermediateObject:(IM *)im { 
    if (self.intermediateObjects.count == 1 && [self.intermediateObjects.containsObject:im]) { 
     [self.managedObjectContext deleteObject:self]; 
    } 
} 
+1

'self.intermediateObjects.count'는 **이 인스턴스를 삭제하기 전에 ** 컬렉션에있는 IM 객체의 수를 제공합니다. 따라서이 하나를 삭제 한 후 하나의 IM 개체를 포함 할 컬렉션을 삭제해야한다면 2와 비교하십시오 – Taco

+0

와우! 이 방법을 완전히 간과했었다. Apple의 Core Data Programming Guide (!!!)에는이 방법에 대한 언급이 없습니다. 이것이 내가 필요한 것이므로, 답으로 표시 할 것입니다. 감사! – GFunkloostar

+0

예 ... 알고 있습니다 ... RTFM;) – GFunkloostar

1

가져온 속성을 사용하여 데이터를 수정하고 있습니까? 이 경우 변경 가능한 컬렉션 접근 자 메서드는 호출되지 않습니다.

사실상 모든 삭제에 더티 플래그를 설정하려면 NSManagedObjectContextObjectsDidChangeNotification 알림에 등록하는 것이 더 좋은 패턴 일 수 있습니다. 삭제 된 개체를 userInfo 사전에서 가져 오려면 NSDeletedObjectsKey 키를 사용하십시오. 그 시간에 컬렉션에 더티 플래그를 설정할 수 있습니다.

+0

Thnx Aaron. 이것이 내 해결책이 될 수 있는지 조사 할 것입니다. 사용자가 컬렉션에 2 개의 CD를 추가했다고 가정 해보십시오. 그리고 그 컬렉션에서 1 CD를 삭제합니다. 내 논리에 따라 1 CD로 컬렉션을 제거 할 수 있습니다. 그래서 나는이 경우 데이터베이스를 스캔하고 그 항목을 삭제합니다. 어떤 알림을 다시 트리거합니다. 그래서 나는이 루프에서 끝나고 더 효율적이되고 싶었습니다. 그래서 while 루프에 넣으십시오 : "더러운"콜렉션이있는 경우, 콜렉션을 스캔하고 콜렉션을 하나의 CD로만 삭제하십시오. while 루프를 다시 시작하십시오. 내가 분명히 자신을 설명하기를 바랍니다. 나는 네가 제안한 것을 시도 할 것이다. 고맙습니다! – GFunkloostar

+0

ps "가져온 속성을 사용하여 데이터 수정"을하는 것이 확실하지 않습니다. – GFunkloostar

+0

실제로 측정 가능한 * 비 효율성이 없다면 시간을 최적화하지 않아도됩니다. 가져온 속성에 대한 [이 링크 참조] (https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdRelationships.html) –