Core data 什么';原语的意义是什么?
Core data 什么';原语的意义是什么?,core-data,ios,key-value-observing,key-value-coding,Core Data,Ios,Key Value Observing,Key Value Coding,-setPrimitiveValue:forKey:不会触发KVO通知。但在我的大脑中,KVO只有在某些事情发生变化时才有意义。但是,当我仅为读取而访问它时,如何更改它呢 -primitiveValueForKey:仅获取某个键的对象。但它不会修改它。那么,为什么在使用-valueForKey:时会/可能会导致KVO通知呢 (当然有一点,但我还不明白。)核心数据主要使用-primitiveValueForKey:和-setPrimitiveValue:forKey:方法。特别是,核心数据不仅需要
-setPrimitiveValue:forKey:
不会触发KVO通知。但在我的大脑中,KVO只有在某些事情发生变化时才有意义。但是,当我仅为读取而访问它时,如何更改它呢
-primitiveValueForKey:
仅获取某个键的对象。但它不会修改它。那么,为什么在使用-valueForKey:
时会/可能会导致KVO通知呢
(当然有一点,但我还不明白。)核心数据主要使用
-primitiveValueForKey:
和-setPrimitiveValue:forKey:
方法。特别是,核心数据不仅需要知道何时修改属性;它还需要知道您何时访问它,以便它可以实现故障处理
因此,核心数据添加了要在getter中使用的-{will,did}AccessValueForKey:
方法,正如-{will,did}ChangeValueForKey:
方法存在于setter中用作KVO挂钩
然而,还有另一个问题:核心数据实际上也为您管理建模属性的底层存储。因此,您需要某种方法在-{will,did}{Access,Change}ValueForKey:
方法建立的屏障内操作此底层存储。这就是-primitivevalue-forKey:
和-setPrimitiveValue:forKey:
的作用
这就是为什么在@property
和@dynamic
存在之前,实现核心数据getter和setter的标准模式是这样的:
// 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
:
// Person.h
@interface Person : NSManagedObject
@property (nonatomic, readwrite, copy) NSString *name;
@end
// Person.m
#import "Person.h"
@implementation Person
@dynamic name;
@end
但是,在某些情况下,您仍然希望在不触发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
注意,我将类continuation放在.m文件中;这并不是编码外部人员(甚至不是真正的编码外部
-awakeFromInsert
和-awakeFromFetch
)应该接触的东西。但它确实可以让我在代码中不嵌入文本字符串的情况下,通过使用实类型,获得“name”属性的底层存储。请将回答的问题标记为已回答,或者如果有什么您不理解的,请在回答的注释中询问。谢谢