NSManagedObjectでTo-Many関連を使用したときにコードの自動生成がされないバグの解決方法
Core Data の NSManagedObject クラスで以下のように To-Many(One-To-Many) 関連を使ったときにコードの自動生成をすると実装コードが生成されない場合があります。
通常の To-Many 関連では問題が起こらないのですが以下のように Ordered(順序) を指定してから NSManagedObject クラスのサブクラスの自動生成をすると実装コード(.m ファイルのコード)の一部が生成されません。
これは Xcode のバグみたいです。最新の Xcode 4.6.1 でも発生しています。
自動生成されないコードはプログラマ自身が実装する必要があります。以下は Transaction(取引) クラスと Journal(仕訳明細) クラスに Ordered の To-Many 関連を設定する場合のコードの実装例です。
#import "Transaction.h" #import "Journal.h" @implementation Transaction @dynamic abstract; @dynamic date; @dynamic entrepreneurNumber; @dynamic journals; static NSString *const kItemsKey = @"journals"; - (void)insertObject:(Journal *)value inJournalsAtIndex:(NSUInteger)idx { NSIndexSet* indexes = [NSIndexSet indexSetWithIndex:idx]; [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey]; NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]]; [tmpOrderedSet insertObject:value atIndex:idx]; [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey]; [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey]; } - (void)removeObjectFromJournalsAtIndex:(NSUInteger)idx { NSIndexSet* indexes = [NSIndexSet indexSetWithIndex:idx]; [self willChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey]; NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]]; [tmpOrderedSet removeObjectAtIndex:idx]; [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey]; [self didChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey]; } - (void)insertJournals:(NSArray *)values atIndexes:(NSIndexSet *)indexes { [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey]; NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]]; [tmpOrderedSet insertObjects:values atIndexes:indexes]; [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey]; [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey]; } - (void)removeJournalsAtIndexes:(NSIndexSet *)indexes { [self willChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey]; NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]]; [tmpOrderedSet removeObjectsAtIndexes:indexes]; [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey]; [self didChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey]; } - (void)replaceObjectInJournalsAtIndex:(NSUInteger)idx withObject:(Journal *)value { NSIndexSet* indexes = [NSIndexSet indexSetWithIndex:idx]; [self willChange:NSKeyValueChangeReplacement valuesAtIndexes:indexes forKey:kItemsKey]; NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]]; [tmpOrderedSet replaceObjectAtIndex:idx withObject:value]; [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey]; [self didChange:NSKeyValueChangeReplacement valuesAtIndexes:indexes forKey:kItemsKey]; } - (void)replaceJournalsAtIndexes:(NSIndexSet *)indexes withJournals:(NSArray *)values { [self willChange:NSKeyValueChangeReplacement valuesAtIndexes:indexes forKey:kItemsKey]; NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]]; [tmpOrderedSet replaceObjectsAtIndexes:indexes withObjects:values]; [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey]; [self didChange:NSKeyValueChangeReplacement valuesAtIndexes:indexes forKey:kItemsKey]; } - (void)addJournalsObject:(Journal *)value { NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]]; NSUInteger idx = [tmpOrderedSet count]; NSIndexSet* indexes = [NSIndexSet indexSetWithIndex:idx]; [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey]; [tmpOrderedSet addObject:value]; [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey]; [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey]; } - (void)removeJournalsObject:(Journal *)value { NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]]; NSUInteger idx = [tmpOrderedSet indexOfObject:value]; if (idx != NSNotFound) { NSIndexSet* indexes = [NSIndexSet indexSetWithIndex:idx]; [self willChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey]; [tmpOrderedSet removeObject:value]; [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey]; [self didChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey]; } } - (void)addJournals:(NSOrderedSet *)values { NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]]; NSMutableIndexSet *indexes = [NSMutableIndexSet indexSet]; NSUInteger valuesCount = [values count]; NSUInteger objectsCount = [tmpOrderedSet count]; for (NSUInteger i = 0; i < valuesCount; ++i) { [indexes addIndex:(objectsCount + i)]; } if (valuesCount > 0) { [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey]; [tmpOrderedSet addObjectsFromArray:[values array]]; [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey]; [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey]; } } - (void)removeJournals:(NSOrderedSet *)values { NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]]; NSMutableIndexSet *indexes = [NSMutableIndexSet indexSet]; for (id value in values) { NSUInteger idx = [tmpOrderedSet indexOfObject:value]; if (idx != NSNotFound) { [indexes addIndex:idx]; } } if ([indexes count] > 0) { [self willChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey]; [tmpOrderedSet removeObjectsAtIndexes:indexes]; [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey]; [self didChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey]; } } @end
Xcode の次のバージョンで修正されると良いのですが...。
関連書籍
Core Dataに関する基礎情報はこちらの本を参考にしてください。