继承自NSObject
及其子类的对象都支持键值编码,并实现了NSKeyValueCoding
协议的方法。该协议的实现依赖我们定义的实例变量(或ivars
)和访问方法。这些方法遵循某些定义好的模式,以便当它收到KVC消息时将key
和属性关联起来,比如valueForKey:
和setValue:forKey:
消息。
通常只需要使用@property
语句声明一个属性,并允许编译器自动生成ivar
和accessor
方法(编译器默认会自动生成)。
如果确实需要在Objective-C中手动实现accessor
方法或ivars
,请遵循本节中的指导原则以保持合规性。 要提供与集合属性交互的附加功能,请实现这篇文章中描述的方法。 如果要键值验证某个对象,请使用KVC之添加验证方法中介绍的方法。
Basic Getter
要实现一个返回属性value
的getter方法,虽然可能做了额外的自定义的操作,但可以使用名称类似属性的方法,比如:
- (NSString*)title
{
// Extra getter logic…
// 额外的逻辑处理
return _title;
}
对于持有布尔值的属性,可以使用以is
为前缀的方法,比如:
- (BOOL)isHidden
{
// Extra getter logic…
return _hidden;
}
当属性是基本数据变量或者结构体,KVC的默认实现是将value
包装在对象中。在 这篇文章中有描述。
Basic Setters
对于hidden
属性的setter方法:
- (void)setHidden:(BOOL)hidden
{
// Extra setter logic…
_hidden = hidden;
}
WARNING
永远不要从
set<Key>:
方法内部调用在验证属性中描述的验证方法。
当属性是非对象类型,比如一个布尔类型hidden
,协议的默认实现是检查底层数据类型,并在将值用于你的setter之前将来自setValue:forKey:
的value
unwrap为对象类型(这种情况下是NSNumber
实例),更多的描述可以查看这篇文章。
如果一个nil
值有可能写入到你的非对象属性,你需要重写setNilValueForKey:
以处理这种情况。
- (void)setNilValueForKey:(NSString *)key
{
if ([key isEqualToString:@"hidden"]) {
[self setValue:@(NO) forKey:@”hidden”];
} else {
[super setNilValueForKey:key];
}
}
实例变量
如果KVC中的一个方法的默认实现不能找到属性的访问方法,它会查询类的accessInstanceVariablesDirectly
方法,以查看该类是否允许直接使用实例变量。默认情况下,该方法返回YES
,我们也可以重写此方法。
如果允许使用ivars
,请确保使用以下划线(_)为前缀的属性名。通常情况下,编译器会在自动生成属性的时候执行了该操作,但是如果使用了@synthesize
,就可以自行执行此命名:
@synthesize title = _title;
在某些情况下,可以使用@dynamic
指令告诉编译器我们将在运行时提供getter和setter,而不是使用@synthesize
指定或编译器自动生成。可以通过这种方法避免自动生成一个getter,以便我们自己可以提供集合访问方法作为代替。更多可以查看Defining Collection Methods
.这种情况下,可以声明ivar
是接口声明的一部分:
@interface MyObject : NSObject {
NSString* _title;
}
@property (nonatomic) NSString* title;
@end
网友评论