3

-setPrimitiveValue:forKey:KVO通知はトリガーされません。しかし、私の頭の中では、KVOは何かが変わったときにのみ意味があります。しかし、読み取りのためだけにアクセスする場合、どうすれば何かを変更できますか?

-primitiveValueForKey:一部のキーのオブジェクトのみを取得します。しかし、それはそれを変更しません。では、なぜこれが使用時にKVO通知を引き起こすのでしょう-valueForKey:か?

(もちろんポイントはありますが、まだわかりません。)

4

1 に答える 1

24

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

于 2010-11-17T23:50:56.733 に答える