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<Key>:
or_set<Key>
, in that order. If found, invoke it with the input value (or unwrapped value, as needed) and finish.
首先去找set<key>或者_set<key> 如果找到 进行赋值。If no simple accessor is found, and if the class method
accessInstanceVariablesDirectly
returnsYES
, look for an instance variable with a name like_<key>
,_is<Key>
,<key>
, oris<Key>
, in that order. If found, set the variable directly with the input value (or unwrapped value) and finish.
如果没有找到第一步的那种方法呢,就需要打开accessInstanceVariablesDirectly 这个方法 返回yes ,然后去找有没有这样命名的_<key>
,_is<Key>
,<key>
, oris<Key>
,如果找到了,就进行赋值操作。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: '[<LGPerson 0x600001be9c20> 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<Key>, <key>, is<Key>, or _<key>,
- (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<Key>
,<key>
,is<Key>
, or_<key>
, in that order. If found, invoke it and proceed to step 5 with the result. Otherwise proceed to the next step.
找到实例方法get<Key>
,<key>
,is<Key>
, or_<key>
,调用执行步骤5 返回结果,没有找到继续执行下一步-
If no simple accessor method is found, search the instance for methods whose names match the patterns
countOf<Key>
andobjectIn<Key>AtIndex:
(corresponding to the primitive methods defined by theNSArray
class) and<key>AtIndexes:
(corresponding to the[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<Key>
,objectIn<Key>AtIndex:
, and<key>AtIndexes:
messages to the key-value coding compliant object that created it. If the original object also implements an optional method with a name likeget<Key>:range:
, 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 anNSArray
, 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<Key>
,enumeratorOf<Key>
, andmemberOf<Key>:
(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<Key>
,enumeratorOf<Key>
, andmemberOf<Key>:
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 anNSSet
, 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_<key>
,_is<Key>
,<key>
, oris<Key>
, 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 ,查找到实例方法诸如: _<key>, _is<Key>, <key>, or is<Key> 的方法 然后执行获取变量的值 执行第五步,否则进入第六步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.
如果都没有就报错了 抛出异常信息