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
accessInstanceVariablesDirectlyreturnsYES, 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 ofNSObjectmay 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 theNSArrayclass) 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
NSArraymethods and return that. Otherwise, proceed to step 3.The proxy object subsequently converts any
NSArraymessages 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
NSSetmethods and return that. Otherwise, proceed to step 4.This proxy object subsequently converts any
NSSetmessage 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 anNSNumberinstance and return that.
如果这个值是 NSNumber 的类型,则将其存储在NSNumber实例变量中返回
If the result is a scalar type not supported by NSNumber, convert to anNSValueobject 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 ofNSObjectmay provide key-specific behavior.
如果都没有就报错了 抛出异常信息










网友评论