辞書を使用してコンテキストに挿入する前に、NSManagedObject のプロパティ値を割り当てようとしています。私が直面している問題は、挿入後にオブジェクトの値がゼロになることです。
私は次のドキュメントに従って作業しています:
NSManagedObject
- (id)initWithEntity:(NSEntityDescription *)entity insertIntoManagedObjectContext:(NSManagedObjectContext *)context
NSManagedObject は、動的クラス生成を使用して、entity.initWithEntity:insertIntoManagedObjectContext に適したクラスのサブクラスを自動的に作成することにより、Objective-C 2 プロパティ機能 (「宣言されたプロパティ」を参照) をサポートします。したがって、エンティティに適切なクラスのインスタンスを返します。動的に生成されたサブクラスは、エンティティによって指定されたクラスに基づいているため、モデルでカスタム クラスを指定すると、alloc に渡されたクラスが置き換えられます。
context が nil でない場合、このメソッドが呼び出されます[context insertObject:self]
(これにより、awakeFromInsert が呼び出されます)。
これは、コンテキストの外部で NSManagedObject を作成し、必要な操作を実行してから、自分でオブジェクトを挿入できることを意味します[context insertObject:self]
これを使用して、次のように NSManagedObject を実装しました。
-(id)initWithDictionary:(NSDictionary *)dict withEntityForName:(NSString *)name insertIntoContext:(NSManagedObjectContext *)context {
NSEntityDescription *entity = [NSEntityDescription entityForName:name inManagedObjectContext:context];
self = [self initWithEntity:entity insertIntoManagedObjectContext:nil];
if (self != nil) {
//Assign all primitive properties
[self primitiveRefreshFromDictionary:dict];
if (context != nil)
[context insertObject:self];
}
return self;
}
私のログによると、オブジェクトは正常に初期化され、そのすべてのプロパティが割り当てられていますが、フェッチされると、すべてのオブジェクトのプロパティは nil でした。だから私はもう少し読んで、見つけました:
awakeFromInsert
レシーバーが最初に管理オブジェクト コンテキストに挿入されたときに、Core Data フレームワークによって自動的に呼び出されます。
- (void)awakeFromInsert
通常、このメソッドを使用して、特別なデフォルト プロパティ値を初期化します。このメソッドは、オブジェクトの存続期間中に 1 回だけ呼び出されます。
値がゼロになる場所があれば、これだと思いました。実装したときの驚きを想像してみてください
-(void)awakeFromInsert {
if (![self primitiveValueForKey:@"wid"]) {
NSLog(@"Nil values here...");
[super awakeFromInsert];
}
}
そして、ログは表示されませんでした。それでも、挿入後、すべてのプロパティは nil です (後で値を変更しても残りません)。
したがって、私の質問は、挿入前にプロパティ値を作成するか、その辞書を awakeFromInsert に持ち込んで、そこに値を割り当てることができるようにする方法です (ドキュメントには、そこに割り当てる必要があると記載されているため)。
「なぜ」という質問を受ける前に、ここに答えがあります。人間的に可能な限りオーバーヘッドを最小限に抑える必要があります。特にNSFetchedResultsControllerを介してUITableViewに接続されているため、すべてが非常にリソースを大量に消費します。非常に一般的なイベントは、各オブジェクトに対して 12 回の挿入 + 15 回のプロパティ変更をトリガーします。これにより得られる最大の利点は、取得する ping の量が非常に少なくなることです。
-controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:
特に、並べ替えられたプロパティの変更によって発生する Move イベントの場合。
どんな助けでも大歓迎です。
乾杯、Z