什么是-primitiveValueForKey:?

Pro*_*ber 2 core-data key-value-observing key-value-coding ios

-setPrimitiveValue:forKey:不会触发KVO通知.但在我的大脑中,KVO只有在发生变化时才有意义.但是当我只是为了阅读而访问它时,怎么能改变呢?

-primitiveValueForKey:只获取某个键的对象.但它不会修改它.那么为什么这会在使用时导致KVO通知-valueForKey:呢?

(当然有一点,但我还没看到.)

Chr*_*son 23

这些-primitiveValueForKey:-setPrimitiveValue:forKey:方法主要由Core Data使用.特别是,Core Data不仅需要知道何时修改属性; 它需要知道你什么时候才能访问它,所以它可以实现错误.

因此,Core Data添加了-{will,did}AccessValueForKey:在getter中使用的方法,就像-{will,did}ChangeValueForKey:在setter中用作KVO钩子的方法一样.

然而,还有另一个问题:Core Data实际上也为您管理建模属性的底层存储.所以你需要一些方法来这些-{will,did}{Access,Change}ValueForKey:方法建立的障碍中操纵这个底层存储.这就是-primitiveValueForKey:-setPrimitiveValue:forKey:进来.

这就是为什么在存在@property和之前实现Core Data getter和setter的标准模式@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
Run Code Online (Sandbox Code Playgroud)

当然,您现在可以声明一个属性并将其定义为@dynamic您希望Core Data在运行时为您生成这些内容:

// Person.h
@interface Person : NSManagedObject
@property (nonatomic, readwrite, copy) NSString *name;
@end

// Person.m
#import "Person.h"

@implementation Person
@dynamic name;
@end
Run Code Online (Sandbox Code Playgroud)

但是,在某些情况下,您仍然希望在没有 KVO或故障触发的情况下操纵底层存储.因此,核心数据也提供了一种新的方法,也可以围绕属性声明和自动综合构建:

// 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
Run Code Online (Sandbox Code Playgroud)

请注意,我将类继续放在.m文件中; 这不是一件码外的人(甚至是真正的代码外-awakeFromInsert-awakeFromFetch)应该接触.但它确实让我得到了"name"属性的底层存储,而没有在我的代码中嵌入文字字符串,并使用真实类型.