-primitiveValueForKey:
andメソッドは、-setPrimitiveValue:forKey:
主にCoreDataによって使用されます。特に、Core Dataは、属性をいつ変更するかを知る必要があるだけではありません。いつアクセスするかを知る必要があるので、障害を実装できます。
したがって、Core Dataは、KVOフックとして機能するセッターで使用するメソッドが存在するの-{will,did}AccessValueForKey:
と同じように、ゲッターで使用するメソッドを追加します。-{will,did}ChangeValueForKey:
ただし、もう1つの問題があります。CoreDataは、モデル化されたプロパティの基になるストレージも実際に管理します。したがって、メソッドによって確立されたバリア内でこの基盤となるストレージを操作するための何らかの方法が必要です-{will,did}{Access,Change}ValueForKey:
。そこ-primitiveValueForKey:
に-setPrimitiveValue:forKey:
来てください。
@property
これが、とが存在する前のCoreDataゲッターとセッターを実装するための標準パターンが次の@dynamic
ようになっていた理由です。
// Person.m
#import "Person.h"
@implementation Person
- (NSString *)name {
[self willAccessValueForKey:@"name"];
NSString *value = [self primitiveValueForKey:@"name"];
[self didAccessValueForKey:@"name"];
}
- (void)setName:(NSString *)value {
[self willChangeValueForKey:@"name"];
[self setPrimitiveValue:value forKey:@"name"];
[self didChangeValueForKey:@"name"];
}
@end
もちろん、プロパティを宣言して@dynamic
、実行時にCoreDataでこのようなものを生成するように定義することもできます。
// Person.h
@interface Person : NSManagedObject
@property (nonatomic, readwrite, copy) NSString *name;
@end
// Person.m
#import "Person.h"
@implementation Person
@dynamic name;
@end
ただし、 KVOや障害発生を行わずに、基盤となるストレージを操作したい場合もあります。したがって、Core Dataはこれを実現するための新しい方法を提供し、プロパティ宣言と自動合成を中心に構築されています。
// Person.h
@interface Person : NSManagedObject
@property (nonatomic, readwrite, copy) NSString *name;
@end
// Person.m
#import "Person.h"
@interface Person ()
@property (nonatomic, readwrite, copy) NSString *primitiveName;
@end
@implementation Person
@dynamic name;
@dynamic primitiveName;
@end
クラス継続を.mファイルに入れていることに注意してください。Personの外部のコード(または実際には外部のコード-awakeFromInsert
と-awakeFromFetch
)が触れるべきものではありません。ただし、コードにリテラル文字列を埋め込むことなく、実際の型を使用して、「name」プロパティの基になるストレージを取得できます。