版本記錄
版本號 | 時間 |
---|---|
V1.0 | 2017.07.27 |
前言
OC是運行時的語言,底層就是運行時,可以說runtime是OC的底層,很多事情也都可以用運行時解決,下面就講述一下運行時runtime的知識以及它的妙用。感興趣的可以看上面幾篇。
1. 運行時runtime深度解析(一)—— API
2. 運行時runtime深度解析(二)—— Method Swizzling在頁面統計上的應用
3. 運行時runtime深度解析(三)—— Method Swizzling在數組越界上的應用
運行時的幾種應用
??前幾篇講了Method Swizzling
在頁面統計和數組越界上的應用,其實runtime
還有很多地方可以使用,比如歸檔解檔、字典轉模型、獲取屬性方法等列表等。可以看下圖,列出了runtime在很多地方的應用。
runtime應用
??這些應用里面,JPatch
熱更新今年已經被蘋果明令禁止了,就不說這個了,大家可以看一下別的方面的應用。這篇文章就主要講一下運行時在獲取類的屬性列表以及方法列表中的應用。
功能實現
下面就以代碼的形式獲取類的屬性列表和方法列表,下面就直接看代碼吧。
1. JJRuntimeVC.h
#import <UIKit/UIKit.h>
@interface JJRuntimeVC : UIViewController
@end
2. JJRuntimeVC.m
#import "JJRuntimeVC.h"
#import <objc/runtime.h>
@interface JJRuntimeVC ()
@property (nonatomic, assign) NSInteger number;
@property (nonatomic, strong) NSMutableArray *arrM;
@end
@implementation JJRuntimeVC
#pragma mark - Override Base Function
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor greenColor];
[self setupUI];
[self loadTimer];
//獲取屬性列表
NSArray *propertyArr = [[self class] loadAllProperties];
NSLog(@"屬性列表 = %@",propertyArr);
//獲取方法列表
NSArray *methodArr = [[self class] loadAllMethods];
NSLog(@"方法列表 = %@",methodArr);
}
#pragma mark - Object Private Function
- (void)setupUI
{
}
- (void)loadTimer
{
}
#pragma mark - Class Public Function
//獲取對象的所有屬性
+ (NSArray *)loadAllProperties
{
u_int count;
//將count的地址傳遞過去
objc_property_t *properties = class_copyPropertyList([self class], &count);
NSMutableArray *propertyListArrM = [NSMutableArray arrayWithCapacity:count];
for (int i = 0; i < count; i++) {
//得到propertyName為c語言的字符串
const char *propertyName = property_getName(properties[i]);
//c字符串轉化為oc字符串
[propertyListArrM addObject:[NSString stringWithCString:propertyName encoding:NSUTF8StringEncoding]];
}
//class_copyPropertyList為底層c語言,我們使用完一定要記得釋放properties
free(properties);
return [propertyListArrM copy];
}
//獲取對象的所有方法
+ (NSArray *)loadAllMethods
{
unsigned int methodCount =0;
Method *methodList = class_copyMethodList([self class],&methodCount);
NSMutableArray *methodsArrM = [NSMutableArray arrayWithCapacity:methodCount];
for(int i = 0; i < methodCount; i++)
{
Method temp = methodList[i];
const char *methodName = sel_getName(method_getName(temp));
int arguments = method_getNumberOfArguments(temp);
const char* encoding = method_getTypeEncoding(temp);
NSLog(@"方法名:%@,參數個數:%d,編碼方式:%@",[NSString stringWithUTF8String:methodName],arguments,[NSString stringWithUTF8String:encoding]);
[methodsArrM addObject:[NSString stringWithUTF8String:methodName]];
}
free(methodList);
return [methodsArrM copy];
}
@end
下面我們看輸出結果
//所有屬性列表輸出
2017-07-29 09:56:42.178020+0800 JJOC[6052:2093168] 屬性列表 = (
number,
arrM
)
//所有方法列表輸出
2017-07-29 09:56:42.178108+0800 JJOC[6052:2093168] 方法名:loadTimer,參數個數:2,編碼方式:v16@0:8
2017-07-29 09:56:42.178141+0800 JJOC[6052:2093168] 方法名:arrM,參數個數:2,編碼方式:@16@0:8
2017-07-29 09:56:42.178202+0800 JJOC[6052:2093168] 方法名:setArrM:,參數個數:3,編碼方式:v24@0:8@16
2017-07-29 09:56:42.178266+0800 JJOC[6052:2093168] 方法名:.cxx_destruct,參數個數:2,編碼方式:v16@0:8
2017-07-29 09:56:42.178314+0800 JJOC[6052:2093168] 方法名:viewDidLoad,參數個數:2,編碼方式:v16@0:8
2017-07-29 09:56:42.178343+0800 JJOC[6052:2093168] 方法名:setupUI,參數個數:2,編碼方式:v16@0:8
2017-07-29 09:56:42.178370+0800 JJOC[6052:2093168] 方法名:number,參數個數:2,編碼方式:q16@0:8
2017-07-29 09:56:42.178396+0800 JJOC[6052:2093168] 方法名:setNumber:,參數個數:3,編碼方式:v24@0:8q16
2017-07-29 09:56:42.178451+0800 JJOC[6052:2093168] 方法列表 = (
loadTimer,
arrM,
"setArrM:",
".cxx_destruct",
viewDidLoad,
setupUI,
number,
"setNumber:"
)
??大家可以看見,所有屬性和方法都被打印了出來,這里大家會發現,屬性的setter
和getter
系統默認的方法也打印了出來,同時還有一個方法.cxx_destruct
被打印了出來,具體是什么我還沒有研究,歡迎知道的@我,謝謝大家。
參考文獻
1. Runtime 10種用法(沒有比這更全的了)
2. Runtime獲取類的屬性列表和方法列表
后記
未完,待續~~
海邊愜意