setValue
接上回介绍 这一节我们来看一下set value 的操作;
我们在这个成员变量来操作演示说明
@interface LGPerson : NSObject{
@public
// NSString *_name;
// NSString *_isName;
// NSString *name;
// NSString *isName;
}
@implementation LGPerson
#pragma mark - 关闭或开启实例变量赋值
+ (BOOL)accessInstanceVariablesDirectly{
return YES;
}
#pragma mark : - setKey. 的流程分析
//- (void)setName:(NSString *)name{
// NSLog(@"%s - %@",__func__,name);
//}
//- (void)_setName:(NSString *)name{
// NSLog(@"1=%s \n- 2=%@",__func__,name);
//}
//
//- (void)setIsName:(NSString *)name{
// NSLog(@"1=%s \n - 2=%@",__func__,name);
//}
LGPerson *person = [[LGPerson alloc] init];
// 1: KVC - 设置值的过程
[person setValue:@"大帅哥" forKey:@"name"];
NSLog(@"%@-%@-%@-%@",person->_name,person->_isName,person->name,person->isName);
NSLog(@"%@-%@-%@",person->_isName,person->name,person->isName);
NSLog(@"%@-%@",person->name,person->isName);
NSLog(@"%@",person->isName);
分别注释掉上面的四种写法成员变量 打印出来的结果验证了在苹果开发者文档的如下内容:
Search Pattern for the Basic Setter
The default implementation of setValue:forKey:
, given key
and value
parameters as input, attempts to set a property named key
to value
(or, for non-object properties, the unwrapped version of value
, as described in Representing Non-Object Values) inside the object receiving the call, using the following procedure:
Look for the first accessor named
set
or: _set
, in that order. If found, invoke it with the input value (or unwrapped value, as needed) and finish.
首先去找set或者_set 如果找到 进行赋值。 If no simple accessor is found, and if the class method
accessInstanceVariablesDirectly
returnsYES
, look for an instance variable with a name like_
,_is
,
, oris
, in that order. If found, set the variable directly with the input value (or unwrapped value) and finish.
如果没有找到第一步的那种方法呢,就需要打开accessInstanceVariablesDirectly 这个方法 返回yes ,然后去找有没有这样命名的_
,_is
,
, oris
,如果找到了,就进行赋值操作。Upon finding no accessor or instance variable, invoke
setValue:forUndefinedKey:
. This raises an exception by default, but a subclass ofNSObject
may provide key-specific behavior.
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key name.'
getValue
// 2: KVC - 取值的过程
person->_name = @"_name";
person->_isName = @"_isName";
person->name = @"name";
person->isName = @"isName";
NSLog(@"取值:%@",[person valueForKey:@"name"]);
//MARK: - valueForKey 流程分析 - get, , is, or _,
- (NSString *)getName{
return NSStringFromSelector(_cmd);
}
- (NSString *)name{
return NSStringFromSelector(_cmd);
}
- (NSString *)isName{
return NSStringFromSelector(_cmd);
}
- (NSString *)_name{
return NSStringFromSelector(_cmd);
}
Search Pattern for the Basic Getter
The default implementation of valueForKey:
, given a key
parameter as input, carries out the following procedure, operating from within the class instance receiving the valueForKey:
call.
Search the instance for the first accessor method found with a name like
get
,
,is
, or_
, in that order. If found, invoke it and proceed to step 5 with the result. Otherwise proceed to the next step.
找到实例方法get
,
,is
, or_
,调用执行步骤5 返回结果,没有找到继续执行下一步-
If no simple accessor method is found, search the instance for methods whose names match the patterns
countOf
andobjectIn
(corresponding to the primitive methods defined by theAtIndex: NSArray
class) and
(corresponding to theAtIndexes: [NSArray](https://developer.apple.com/library/archive/documentation/LegacyTechnologies/WebObjects/WebObjects_3.5/Reference/Frameworks/ObjC/Foundation/Classes/NSArrayClassCluster/Description.html#//apple_ref/occ/cl/NSArray)
methodobjectsAtIndexes:
).If the first of these and at least one of the other two is found, create a collection proxy object that responds to all
NSArray
methods and return that. Otherwise, proceed to step 3.The proxy object subsequently converts any
NSArray
messages it receives to some combination ofcountOf
,objectIn
, andAtIndex:
messages to the key-value coding compliant object that created it. If the original object also implements an optional method with a name likeAtIndexes: get
, the proxy object uses that as well, when appropriate. In effect, the proxy object working together with the key-value coding compliant object allows the underlying property to behave as if it were an:range: NSArray
, even if it is not.
数组的判断处理 -
If no simple accessor method or group of array access methods is found, look for a triple of methods named
countOf
,enumeratorOf
, andmemberOf
(corresponding to the primitive methods defined by the: [NSSet](https://developer.apple.com/library/archive/documentation/LegacyTechnologies/WebObjects/WebObjects_3.5/Reference/Frameworks/ObjC/Foundation/Classes/NSSetClassCluster/Description.html#//apple_ref/occ/cl/NSSet)
class).If all three methods are found, create a collection proxy object that responds to all
NSSet
methods and return that. Otherwise, proceed to step 4.This proxy object subsequently converts any
NSSet
message it receives into some combination ofcountOf
,enumeratorOf
, andmemberOf
messages to the object that created it. In effect, the proxy object working together with the key-value coding compliant object allows the underlying property to behave as if it were an: NSSet
, even if it is not.
NSSet的判断处理 If no simple accessor method or group of collection access methods is found, and if the receiver's class method
[accessInstanceVariablesDirectly](https://developer.apple.com/library/archive/documentation/LegacyTechnologies/WebObjects/WebObjects_3.5/Reference/Frameworks/ObjC/EOF/EOControl/Classes/NSObjectAdditions/Description.html#//apple_ref/occ/clm/NSObject/accessInstanceVariablesDirectly)
returnsYES
, search for an instance variable named_
,_is
,
, oris
, in that order. If found, directly obtain the value of the instance variable and proceed to step 5. Otherwise, proceed to step 6.
非集合类型:如果accessInstanceVariablesDirectly 返回yes ,查找到实例方法诸如: _, _is , , or is 的方法 然后执行获取变量的值 执行第五步,否则进入第六步 If the retrieved property value is an object pointer, simply return the result.
如果检测到的属性值是对象指针,则返回结果。
If the value is a scalar type supported byNSNumber
, store it in anNSNumber
instance and return that.
如果这个值是 NSNumber 的类型,则将其存储在NSNumber实例变量中返回
If the result is a scalar type not supported by NSNumber, convert to anNSValue
object and return that.
如果结果是NSNumber 不支持的标量类型,那马转换NSValue对象返回If all else fails, invoke
[valueForUndefinedKey:](https://developer.apple.com/documentation/objectivec/nsobject/1413457-value)
. This raises an exception by default, but a subclass ofNSObject
may provide key-specific behavior.
如果都没有就报错了 抛出异常信息