1.獲取成員變量列表
1.1相關(guān)函數(shù)
Ivar可以看出也是一個(gè)變量類(lèi)型
typedef struct objc_ivar *Ivar;
//獲取成員變量列表
Ivar *class_copyIvarList(Class cls, unsigned int * outCount)
//獲取成員變量類(lèi)型編碼
const char *ivar_getTypeEncoding(Ivar v)
//獲取成員變量名稱(chēng)
const char *ivar_getName(Ivar v)
1.2實(shí)例代碼
#import "ViewController.h"
#import <objc/runtime.h>
@interface ViewController ()
@property (nonatomic,strong)NSString *name;
@property (nonatomic,assign)NSString *age;
@property (nonatomic,strong)NSString *address;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self class_copyIvarList];
}
- (void)class_copyIvarList{
uint count;
Ivar *ivars = class_copyIvarList([self class], &count);
for (unsigned int i = 0; i < count; i ++) {
Ivar ivar = ivars[i];
//獲取成員變量名稱(chēng)
NSString* name = @(ivar_getName(ivar));
//獲取成員變量數(shù)據(jù)類(lèi)型
NSString * type = @(ivar_getTypeEncoding(ivar));
NSLog(@"類(lèi)型為 %@ 的 %@ ",type, name);
}
free(ivars);
}
1.3打印數(shù)據(jù)
2018-05-26 10:02:36.597199+0700 runTimer[6417:1017717] 類(lèi)型為 @"NSString" 的 _name
2018-05-26 10:02:36.597586+0700 runTimer[6417:1017717] 類(lèi)型為 @"NSString" 的 _age
2018-05-26 10:02:36.597852+0700 runTimer[6417:1017717] 類(lèi)型為 @"NSString" 的 _address
1.4查漏補(bǔ)缺
//通過(guò)變量名稱(chēng)獲取類(lèi)中的實(shí)例成員變量
Ivar class_getInstanceVariable(Class cls, const char * name)
實(shí)例代碼及打印數(shù)據(jù):
#import "ViewController.h"
#import <objc/runtime.h>
@interface ViewController ()
@property (nonatomic,strong)NSString *name;
@property (nonatomic,assign)NSString *age;
@property (nonatomic,strong)NSString *address;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self class_getInstanceVariable];
}
- (void)class_getInstanceVariable{
//注意成員變量必須“_名稱(chēng)”
Ivar name_Ivar = class_getInstanceVariable([self class], "_name");
NSString * name_type = @(ivar_getTypeEncoding(name_Ivar));
NSString *name_str = @(ivar_getName(name_Ivar));
NSLog(@"name_type:%@",name_type);
NSLog(@"name_str:%@",name_str);
}
打印數(shù)據(jù):
2018-05-26 10:41:17.384676+0700 runTimer[7091:1043835] name_type:@"NSString"
2018-05-26 10:41:17.384831+0700 runTimer[7091:1043835] name_str:_name
2.添加成員變量
2.1相關(guān)函數(shù)
//為元類(lèi)添加成員變量
BOOL class_addIvar(Class cls, const char * name, size_t size,
uint8_t alignment, const char * types)
//添加類(lèi) superclass 類(lèi)是父類(lèi) name 類(lèi)的名字 size_t 類(lèi)占的空間
Class objc_allocateClassPair(Class superclass, const char * name,size_t extraBytes)
//注冊(cè)類(lèi)
void objc_registerClassPair(Class cls)
//銷(xiāo)毀類(lèi)
void objc_disposeClassPair(Class _Nonnull cls)
2.2實(shí)例代碼
- People.h
#import <Foundation/Foundation.h>
@interface People : NSObject
@end
- People.m
#import "People.h"
@implementation People
@end
3.實(shí)例調(diào)用:
#import "ViewController.h"
#import <objc/runtime.h>
#import "People.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self class_addIvar];
}
- (void)class_addIvar{
Class P_Class = objc_allocateClassPair([NSObject class], "_People", 0);
BOOL isOk = NO;
isOk = class_addIvar(P_Class,"myVar", sizeof(id), log2(sizeof(id)), "@");
isOk == YES ? nil : NSLog(@"failed on class_addIvar");
objc_registerClassPair(P_Class);
id myobj = [[P_Class alloc] init];
[myobj setValue:@"test" forKey:@"myVar"];
NSLog(@"myVar: %@", [myobj valueForKey:@"myVar"]);
myobj = nil;//當(dāng)_People類(lèi)或者它的子類(lèi)的實(shí)例還存在绒怨,則不能調(diào)用objc_disposeClassPair這個(gè)方法;因此這里要先銷(xiāo)毀實(shí)例對(duì)象后才能銷(xiāo)毀類(lèi)谦疾;
objc_disposeClassPair(P_Class);
}
打印數(shù)據(jù):
2018-05-27 10:19:51.251273+0700 runTimer[14245:1323729] myVar: test
總結(jié):
關(guān)于這個(gè)方法南蹂,說(shuō)真的讓我產(chǎn)生了一些疑惑,至今也沒(méi)有得到答案念恍,也希望看到這篇文章對(duì)runtime有一定理解朋友可以給予一定的解釋?zhuān)?/p>
- 疑問(wèn)一:objc_allocateClassPair 在剛開(kāi)始我創(chuàng)建獲取元類(lèi)時(shí)我得到總是nil六剥,在網(wǎng)上查了很多資料但是我沒(méi)有得到答案晚顷,后來(lái)是因?yàn)樽约菏切缘脑诶勖凹印癬” 竟然成功的獲取了,我沒(méi)有明白原因疗疟。
- 疑問(wèn)二:關(guān)于元類(lèi)說(shuō)實(shí)話(huà)我之前也是簡(jiǎn)單的知道该默,個(gè)人理解是關(guān)于類(lèi)描述的一個(gè)類(lèi),但是我始終不能明白在元類(lèi)中添加成員變量策彤,這樣做會(huì)蘋(píng)果官方有什么樣的深意栓袖。
3 object_setIvar object_getIvar
3.1相關(guān)函數(shù)
//相當(dāng)于set方法
void object_setIvar(id obj, Ivar ivar, id value)
//相當(dāng)于get方法
id object_getIvar(id obj, Ivar ivar)
3.2實(shí)例代碼
1.People.h
#import <Foundation/Foundation.h>
@interface People : NSObject
@property (nonatomic,strong)NSString *phone;
@end
- People.m
#import "People.h"
@implementation People
@end
3.實(shí)例代碼調(diào)用:
#import "ViewController.h"
#import <objc/runtime.h>
#import <objc/message.h>
#import "People.h"
@interface ViewController ()
@property (nonatomic,strong)People *p;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
Ivar ivar = class_getInstanceVariable([People class], "_phone");
People *p = [[People alloc] init];
p.phone = @"1322432423";
id name1 = object_getIvar(p, ivar);
NSLog(@"name1:%@",name1);
object_setIvar(p, ivar, @"1322432423");
id name2 = object_getIvar(p, ivar);
NSLog(@"name2:%@",name2);
}
打印數(shù)據(jù):
2018-05-27 11:05:04.551576+0700 runTimer[14991:1353337] name1:1322432423
2018-05-27 11:05:04.551717+0700 runTimer[14991:1353337] name2:1322432423
總結(jié):
看到這里的時(shí)候我想大家已經(jīng)很明白了 這兩個(gè)方法 基本上等同于set get方法。
4.未做解析方法:
ivar_getOffset
class_setWeakIvarLayout
object_setIvarWithStrongDefault
class_getWeakIvarLayout
class_getIvarLayout
好了 就那么多了 還有一些方法沒(méi)有講店诗,太懶了裹刮,就不一一解析了。
下一章庞瘸,關(guān)于runtime 關(guān)于method的解析