iOS底層原理總結--OC對象的分類:instance、class、meta-calss對象的isa和superclass - 掘金post
...atom
本文是根據 iOS底層原理總結-- KVO/KVC的本質 - 掘金 延展的一篇文章,因此獲取的方法列表爲添加kvo監聽後,子類內部方法列表爲例子。spa
請先瀏覽 iOS底層原理總結-- KVO/KVC的本質 - 掘金 文章後閱讀本文。指針
代碼會在 ( iOS底層原理總結-- KVO/KVC的本質 - KVO的代碼實現 ) 此段代碼的基礎上進行更改,code
iOS底層原理總結-- KVO/KVC的本質 - KVO的代碼實現orm
#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
複製代碼
打印結果cdn
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
... 持續更新