KVC原理浅析学习<3>

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:

  1. 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 如果找到 进行赋值。

  2. If no simple accessor is found, and if the class method accessInstanceVariablesDirectly returns YES, look for an instance variable with a name like _, _is, , or is, in that order. If found, set the variable directly with the input value (or unwrapped value) and finish.
    如果没有找到第一步的那种方法呢,就需要打开accessInstanceVariablesDirectly 这个方法 返回yes ,然后去找有没有这样命名的 _, _is, , or is,如果找到了,就进行赋值操作。

  3. Upon finding no accessor or instance variable, invoke setValue:forUndefinedKey:. This raises an exception by default, but a subclass of NSObject 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.

  1. 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 返回结果,没有找到继续执行下一步

  2. If no simple accessor method is found, search the instance for methods whose names match the patterns countOf and objectInAtIndex: (corresponding to the primitive methods defined by the NSArray class) and 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) method objectsAtIndexes:).

    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 of countOf, objectInAtIndex:, and AtIndexes: messages to the key-value coding compliant object that created it. If the original object also implements an optional method with a name like get: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 an NSArray, even if it is not.
    数组的判断处理

  3. If no simple accessor method or group of array access methods is found, look for a triple of methods named countOf, enumeratorOf, and memberOf: (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 of countOf, enumeratorOf, and memberOf: 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的判断处理

  4. 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) returns YES, search for an instance variable named _, _is, , or is, 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 的方法 然后执行获取变量的值 执行第五步,否则进入第六步

  5. If the retrieved property value is an object pointer, simply return the result.
    如果检测到的属性值是对象指针,则返回结果。
    If the value is a scalar type supported by NSNumber, store it in an NSNumber instance and return that.
    如果这个值是 NSNumber 的类型,则将其存储在NSNumber实例变量中返回
    If the result is a scalar type not supported by NSNumber, convert to an NSValue object and return that.
    如果结果是NSNumber 不支持的标量类型,那马转换NSValue对象返回

  6. If all else fails, invoke [valueForUndefinedKey:](https://developer.apple.com/documentation/objectivec/nsobject/1413457-value). This raises an exception by default, but a subclass of NSObject may provide key-specific behavior.
    如果都没有就报错了 抛出异常信息

你可能感兴趣的:(KVC原理浅析学习<3>)