iOS底层原理总结篇-- 深入理解 KVC\KVO 实现机制(获取类对象中的方法列表篇)...

iOS底层原理总结--OC对象的本质(一) - 掘金

iOS底层原理总结--OC对象的本质(二) - 掘金

iOS底层原理总结--OC对象的分类:instance、class、meta-calss对象的isa和superclass - 掘金

iOS底层原理总结-- KVO/KVC的本质 - 掘金

...

一. 前言

本文是根据 iOS底层原理总结-- KVO/KVC的本质 - 掘金 延展的一篇文章,所以获取的方法列表为添加kvo监听后,子类内部方法列表为例子。

请先浏览 iOS底层原理总结-- KVO/KVC的本质 - 掘金 文章后阅读本文。

代码会在 ( iOS底层原理总结-- KVO/KVC的本质 - KVO的代码实现 ) 此段代码的基础上进行更改,

KVO的实现代码

iOS底层原理总结-- KVO/KVC的本质 - KVO的代码实现

获取对象方法列表代码实现

#import "ViewController.h"
#import "DLPerson.h"
#import <objc/runtime.h>
@interface ViewController ()
@property (nonatomic, strong) DLPerson *person1;
@property (nonatomic, strong) DLPerson *person2;
@end

@implementation ViewController

/**
 * 获取对象方法列表
 */
- (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 appendFormat:@"%@, ", methodName];
    }
    
    /// 释放  C语言需要释放
    free(methodList);
    
    /// 打印方法名
    NSLog(@"%@  %@", cls, methodNames);
}

- (void)viewDidLoad {
    [super viewDidLoad];
    self.person1 = [[DLPerson alloc]init];
    self.person1.age = 10;
    self.person2 = [[DLPerson alloc]init];
    self.person2.age = 1;
    
    ///> person1添加kvo监听
    NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;
    [self.person2 addObserver:self forKeyPath:@"age" options:options context:nil];
    
    
    [self printMethodNamesOfClass: object_getClass(self.person1)];
    [self printMethodNamesOfClass: object_getClass(self.person2)];
    
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
    [self.person1 setAge:20];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
    NSLog(@"监听到了%@的%@属性发生了改变%@",object,keyPath,change);
}

- (void)dealloc{
    ///> 使用结束后记得移除
    [self.person1 removeObserver:self forKeyPath:@"age"];
}
@end

复制代码

打印结果


    DLPerson  setAge:, age,
    
    NSKVONotifying_DLPerson  setAge:, class, dealloc, _isKVOA,
    
复制代码
打印结果分析

由打印结果可得出 当一个对象添加了KVO的监听时,当前对象的isa指针指向的就不是你原来的类,指向的是另外一个类对象,如下图

第一行打印 为person1的方法列表,未添加KVO监听, isa直接指向的是DLPerson只有age的set和get方法

第二行打印 为person2的方法列表,person添加KVO监听后 isa指针指向的是NSKVONotifying_DLPerson CLass对象 方法列表包含了 delloc _isKVOA 和 setAge

... 持续更新

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值