-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」プロパティの基になるストレージを取得できます。