04. KVO使用,原理,本质

2021-01-05  本文已影响0人  ProfessorFan

问题

  1. KVO日常使用
  2. KVO原理(KVO本质是什么)
  3. 如何手动触发KVO
  4. 直接修改成员变量会触发KVO吗
  5. KVO图解
  6. 获取一个Class 对象的方法列表

答案

  1. KVO日常使用
#import <Foundation/Foundation.h>

@interface MJCat : NSObject
@property (assign, nonatomic) int weight;
@end

@interface MJPerson : NSObject
@property (assign, nonatomic) int age;

@property (assign, nonatomic) MJCat *cat;
@end

@implementation MJCat

@end

@implementation MJPerson

//- (void)setAge:(int)age
//{
//    _age = age;
//
//    NSLog(@"setAge: - %d", age);
//}

@end

@interface MJObserver : NSObject

@end

@implementation MJObserver

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
    NSLog(@"observeValueForKeyPath - %@", change);
}

@end



int main(int argc, const char * argv[]) {
    @autoreleasepool {
        MJObserver *observer = [[MJObserver alloc] init];
        MJPerson *person = [[MJPerson alloc] init];
        
        // 添加KVO监听
        [person addObserver:observer forKeyPath:@"age" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:NULL];
        
        // 通过KVC修改age属性
        [person setValue:@10 forKey:@"age"];
        
        // setAge:
        
        // 移除KVO监听
        [person removeObserver:observer forKeyPath:@"age"];
        
        
//        person.age = 10;
        
//        NSLog(@"%@", [person valueForKey:@"age"]);
//        NSLog(@"%@", [person valueForKeyPath:@"cat.weight"]);
        
        
//        NSLog(@"%d", person.age);
        
//        [person setValue:[NSNumber numberWithInt:10] forKey:@"age"];
//        [person setValue:@10 forKey:@"age"];
//        person.cat = [[MJCat alloc] init];
//        [person setValue:@10 forKeyPath:@"cat.weight"];
        
//        NSLog(@"%d", person.age);
        
    
    }
    return 0;
}
  1. KVO原理(KVO本质是什么)
  1. 如何手动触发KVO
  1. 直接修改成员变量会触发KVO吗
  1. KVO图解


    KVO图解.png
  2. 获取一个Class 对象的方法列表

#import <objc/runtime.h>

- (void)printMethodNamesOfClass:(Class)cls
{
    unsigned int count;
    // 获得方法数组
    Method *methodList = class_copyMethodList(cls, &count);
    
    // 存储方法名
    NSMutableString *methodNames = [NSMutableString string];
    
    // 遍历所有的方法
    for (int i = 0; i < count; i++) {
        // 获得方法
        Method method = methodList[i];
        // 获得方法名
        NSString *methodName = NSStringFromSelector(method_getName(method));
        // 拼接方法名
        [methodNames appendString:methodName];
        [methodNames appendString:@", "];
    }
    
    // 释放
    free(methodList);
    
    // 打印方法名
    NSLog(@"%@ %@", cls, methodNames);
}

# 测试

  self.person1 = [[MJPerson alloc] init];
  self.person1.age = 1;
    
  self.person2 = [[MJPerson alloc] init];
  self.person2.age = 2;
    
    // 给person1对象添加KVO监听
  NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;
  [self.person1 addObserver:self forKeyPath:@"age" options:options context:@"123"];
    
  [self printMethodNamesOfClass:object_getClass(self.person1)];
  [self printMethodNamesOfClass:object_getClass(self.person2)];
# 结果
2021-01-05 19:32:33.868603+0800 Interview01[4816:567497] NSKVONotifying_MJPerson setAge:, class, dealloc, _isKVOA,
2021-01-05 19:32:33.868817+0800 Interview01[4816:567497] MJPerson setAge:, age,
上一篇下一篇

猜你喜欢

热点阅读