iOS runtime(二)runtime之Ivar 详尽

runtime官方文章学习大纲

1.获取成员变量列表

1.1相关函数

Ivar可以看出也是一个变量类型
typedef struct objc_ivar *Ivar;
//获取成员变量列表
Ivar *class_copyIvarList(Class cls, unsigned int * outCount) 
//获取成员变量类型编码
const char *ivar_getTypeEncoding(Ivar  v) 
//获取成员变量名称
const char *ivar_getName(Ivar  v) 

1.2实例代码

#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];
        //获取成员变量名称
        NSString* name = @(ivar_getName(ivar));
        //获取成员变量数据类型
        NSString * type = @(ivar_getTypeEncoding(ivar));
        NSLog(@"类型为 %@ 的 %@ ",type, name);
    }
    free(ivars);
}

1.3打印数据

2018-05-26 10:02:36.597199+0700 runTimer[6417:1017717] 类型为 @"NSString" 的 _name 
2018-05-26 10:02:36.597586+0700 runTimer[6417:1017717] 类型为 @"NSString" 的 _age 
2018-05-26 10:02:36.597852+0700 runTimer[6417:1017717] 类型为 @"NSString" 的 _address 

1.4查漏补缺

 //通过变量名称获取类中的实例成员变量
 Ivar class_getInstanceVariable(Class cls, const char * name)

实例代码及打印数据:

#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{
    //注意成员变量必须“_名称”
    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);
}
打印数据:
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相关函数

//为元类添加成员变量
BOOL class_addIvar(Class cls, const char * name, size_t size, 
              uint8_t alignment, const char * types) 
//添加类 superclass 类是父类   name 类的名字  size_t 类占的空间
Class objc_allocateClassPair(Class superclass, const char * name,size_t extraBytes) 
//注册类
void objc_registerClassPair(Class  cls) 
//销毁类
void objc_disposeClassPair(Class _Nonnull cls) 

2.2实例代码

  1. People.h
#import <Foundation/Foundation.h>

@interface People : NSObject

@end
  1. People.m
#import "People.h"

@implementation People

@end

3.实例调用:

#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;//当_People类或者它的子类的实例还存在,则不能调用objc_disposeClassPair这个方法;因此这里要先销毁实例对象后才能销毁类;
    objc_disposeClassPair(P_Class);
    
}
打印数据:
2018-05-27 10:19:51.251273+0700 runTimer[14245:1323729] myVar: test

总结:
关于这个方法,说真的让我产生了一些疑惑,至今也没有得到答案,也希望看到这篇文章对runtime有一定理解朋友可以给予一定的解释,

  • 疑问一:objc_allocateClassPair 在刚开始我创建获取元类时我得到总是nil,在网上查了很多资料但是我没有得到答案,后来是因为自己是性的在累名前加“_” 竟然成功的获取了,我没有明白原因。
  • 疑问二:关于元类说实话我之前也是简单的知道,个人理解是关于类描述的一个类,但是我始终不能明白在元类中添加成员变量,这样做会苹果官方有什么样的深意。

3 object_setIvar object_getIvar

3.1相关函数

//相当于set方法
void object_setIvar(id obj, Ivar ivar, id value) 
//相当于get方法
id object_getIvar(id obj, Ivar ivar) 

3.2实例代码

1.People.h

#import <Foundation/Foundation.h>

@interface People : NSObject
@property (nonatomic,strong)NSString *phone;
@end

  1. People.m
#import "People.h"

@implementation People

@end

3.实例代码调用:

#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);
}
打印数据:
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

总结:
看到这里的时候我想大家已经很明白了 这两个方法 基本上等同于set get方法。

4.未做解析方法:

ivar_getOffset
class_setWeakIvarLayout
object_setIvarWithStrongDefault
class_getWeakIvarLayout
class_getIvarLayout

好了 就那么多了 还有一些方法没有讲,太懒了,就不一一解析了。
下一章,关于runtime 关于method的解析

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,444评论 4 365
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,867评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,157评论 0 248
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,312评论 0 214
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,673评论 3 289
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,802评论 1 223
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,010评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,743评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,470评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,696评论 2 250
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,187评论 1 262
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,538评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,188评论 3 240
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,127评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,902评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,889评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,741评论 2 274

推荐阅读更多精彩内容

  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 29,029评论 8 265
  • 引导 对于从事 iOS 开发人员来说,所有的人都会答出「 Runtime 是运行时 」,什么情况下用 Runtim...
    Winny_园球阅读 4,150评论 3 75
  • 文/不会说谎的小丑 01 最近在朋友圈都在传播一则新闻,很是好奇,我仔细看了看。是有关于绑架事件,而且受害人都是2...
    啞白先生阅读 502评论 0 4
  • 迷茫,曾是自己为了逃避奋斗而找的似乎理所当然的理由,然而那只是借口。 有本书中说“迷茫,是因为你的才华撑不起你的理...
    醒心远志阅读 303评论 0 1
  • 初二随着公公婆婆、老公的兄妹们一起到乡下去给老公的舅舅们拜年了! 我的老家在城里,我这边的亲戚们也都在城里,相隔都...
    精进的医生阅读 630评论 69 61