2011-08-16 1 views
1

코어 데이터를 사용하기 위해 개조 중 인 iOS 4 이상 앱이 있습니다. 나는 "Entity"Article "을 가지고 있는데 이것은 다른 Entity"MediaResource "와 to-many 관계를 가지고 있으며 각각에 대해 NSManagedObject 서브 클래스를 생성했다. 이 관계를 "미디어"라고하며 선택 사항으로 설정하고 연결된 MediaResource 객체를 계단식으로 삭제합니다. 이 기사에는 역으로 하나가 있습니다.iOS 코어 생성 된 접근자를 사용하여 객체를 제거 할 때 데이터 대다 관계가 깨집니다.

- (void)addMediaObject:(MediaResource *)value {  
    NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1]; 
    [self willChangeValueForKey:@"media" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects]; 
    [[self primitiveValueForKey:@"media"] addObject:value]; 
    [self didChangeValueForKey:@"media" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects]; 
    [changedObjects release]; 
} 

- (void)removeMediaObject:(MediaResource *)value { 
    NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1]; 
    [self willChangeValueForKey:@"media" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects]; 
    [[self primitiveValueForKey:@"media"] removeObject:value]; 
    [self didChangeValueForKey:@"media" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects]; 
    [changedObjects release]; 
} 

- (void)addMedia:(NSSet *)value {  
    [self willChangeValueForKey:@"media" withSetMutation:NSKeyValueUnionSetMutation usingObjects:value]; 
    [[self primitiveValueForKey:@"media"] unionSet:value]; 
    [self didChangeValueForKey:@"media" withSetMutation:NSKeyValueUnionSetMutation usingObjects:value]; 
} 

- (void)removeMedia:(NSSet *)value { 
    [self willChangeValueForKey:@"media" withSetMutation:NSKeyValueMinusSetMutation usingObjects:value]; 
    [[self primitiveValueForKey:@"media"] minusSet:value]; 
    [self didChangeValueForKey:@"media" withSetMutation:NSKeyValueMinusSetMutation usingObjects:value]; 
} 

어디 여기에는 NSMutableSets이 없습니다,하지만 난 자동 생성 된 코드가 무엇을 알고 가정

생성 된 코드는 유형 NSSet의 특성 * 미디어 기사 클래스뿐만 아니라, 이러한 방법을 포함 하고있다.

나는 이런 식으로 다음 기사를 추가 그것에 MediaResource 개체를 추가하고이를 수행 할 수 있습니다

  [newArticle addMediaObject:newMediaObject]; 

나는 올바른 방법입니다 문서에서 수집합니다. 그러나, 나는 또한 mutableSetValueForKey: 사용에 대한 참조를 볼 수 있지만 여기에 적용되지 않습니다.

기본적으로, 주어진 실행 중에 기사를 추가하고 제거한 다음 정상적으로 작동 할 수 있습니다. 그런 다음 추가 한 다음 응용 프로그램을 종료했다가 다시 실행 한 다음 제거하면 NSSet에서 객체를 제거하라는 예외가 발생합니다. 물론 제거 할 수 없습니다. 실제로 이러한 방법을 쓰지 않았기 때문에 혼란 스럽습니다. 어떤 아이디어? 다음은 관련 스택 추적입니다.

2011-08-16 11:12:32.141 MyApp[41825:207] -[__NSSet0 removeObject:]: unrecognized selector sent to instance 0x8041f60 
2011-08-16 11:12:32.144 MyApp[41825:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSSet0 removeObject:]: unrecognized selector sent to instance 0x8041f60' 
*** Call stack at first throw: 
(
    0 CoreFoundation      0x01a5b5a9 __exceptionPreprocess + 185 
    1 libobjc.A.dylib      0x01baf313 objc_exception_throw + 44 
    2 CoreFoundation      0x01a5d0bb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187 
    3 CoreFoundation      0x019cc966 ___forwarding___ + 966 
    4 CoreFoundation      0x019cc522 _CF_forwarding_prep_0 + 50 
    5 CTKennedy       0x000b292c -[Article removeMediaObject:] + 220 
    6 CoreData       0x0054a1f2 -[NSManagedObject(_NSInternalMethods) _excludeObject:fromPropertyWithKey:andIndex:] + 98 
    7 CoreData       0x0053f7d1 -[NSManagedObject(_NSInternalMethods) _maintainInverseRelationship:forProperty:oldDestination:newDestination:] + 449 
    8 CoreData       0x00593b55 -[NSManagedObject(_NSInternalMethods) _propagateDelete:] + 1541 
    9 CoreData       0x0054a02a -[NSManagedObject(_NSInternalMethods) _propagateDelete] + 42 
    10 CoreData       0x00549e53 -[NSManagedObjectContext(_NSInternalChangeProcessing) _propagateDeletesUsingTable:] + 515 
    11 CoreData       0x00549c12 -[NSManagedObjectContext(_NSInternalChangeProcessing) _processDeletedObjects:] + 146 
    12 CoreData       0x0053cba8 -[NSManagedObjectContext(_NSInternalChangeProcessing) _propagatePendingDeletesAtEndOfEvent:] + 104 
    13 CoreData       0x00508982 -[NSManagedObjectContext(_NSInternalChangeProcessing) _processRecentChanges:] + 754 
    14 CoreData       0x00542715 -[NSManagedObjectContext save:] + 149 
+0

안녕하세요, 핵심 데이터를 여러 접근 자로 대체하려고합니다. 솔루션이 작동합니까? 또는 mutableSet 사용해야합니까? –

답변

3

자동 생성 코드로 인해 문제가 발생하지 않았습니다. 코어 데이터는 실제로 NSSet에 대한 클래스 클러스터를 사용하고 다 대다 관계에 액세스 할 때 anther 클래스 _NSFaultingMutableSet을 반환하기 때문에 변경 가능한 세트가 표시되지 않습니다. NSSet은 정의 된 메소드를 사용하지 않고 다른 클래스가 관계 설정을 시도하지 못하도록하기 위해 헤더에 사용됩니다.

에 대한 대다 관계가 betas 인 생성 된 클래스 Alpha이 있습니다. 나는이 방법의 첫 번째 줄에 중단 점을 넣을 경우

-(void)addBetasObject:(NSManagedObject *)value {  
    NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1]; 
    [self willChangeValueForKey:@"betas" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects]; 
    [[self primitiveValueForKey:@"betas"] addObject:value]; 
    [self didChangeValueForKey:@"betas" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects]; 
    [changedObjects release]; 
} 

... 난 다음 디버거 프롬프트에서이 작업을 수행 할 수 있습니다

(gdb) po [self primitiveValueForKey:@"betas"] 
Relationship objects for {(
)} on 0x4d45e20 
(gdb) po [[self primitiveValueForKey:@"betas"] class] 
_NSFaultingMutableSet 

그래서, 헤더에도 불구하고, 속성이있다 변경 가능한 세트는 사용자 정의 된 것입니다.

마찬가지로, 일치하는 방법 :

- (void)removeBetasObject:(NSManagedObject *)value { 
    NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1]; 
    [self willChangeValueForKey:@"betas" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects]; 
    [[self primitiveValueForKey:@"betas"] removeObject:value]; 
    [self didChangeValueForKey:@"betas" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects]; 
    [changedObjects release]; 
} 

... 슈팅을 막아 후, 디버거 제공 : 무대 뒤에서

(gdb) po [self primitiveValueForKey:@"betas"] 
Relationship objects for {(
    <Beta: 0x4d4be40> (entity: Beta; id: 0x4d52510 <x-coredata://64E86DEC-53DA-4197-B1F3-6C0007576100/Beta/p1> ; data: { 
    alphas =  (
     "0x4d52140 <x-coredata://64E86DEC-53DA-4197-B1F3-6C0007576100/Alpha/p1>" 
    ); 
    num = 0; 
}) 
)} on 0x4d45e20 
(gdb) po [[self primitiveValueForKey:@"betas"] class] 
_NSFaultingMutableSet 

이 수업 시간에 변경

때문에 @dynamic 프로세서 지시어의 발생 betas의 경우, 즉 @dynamic betas;이고 해당 행이 제거되면 속성은 순전히 헤더에있는대로 정의됩니다.

@dynamic media;에 대한 Article.m 파일을 확인하십시오. 누락되었거나 문제의 원인이되는 @synthesize media;입니다.

관련 문제