对于Objective-C runtime的浅薄认知(二)

在上一篇runtime中我们了解到了对象, 类的结构体定义,了解到元类的定义, 对象,类结构体中isa指针的指向等,这篇我们将进入实战,该篇对于在编码过程中有很大的帮助,减少项目中的代码量。
1.关联对象(Associated Object)
关联对象类适用于动态添加属性, 我们利用OC的运行时特性,在分类中添加一个属性.我们可以把关联对象想象成一个OC的对象(如字典), 这个对象通过给定的key连接到这个类的实例上, 由于使用的是C接口, 所以key是一个void指针(const void *). 我们还需要指定的一个内存管理策略, 用来确定如何管理这个对象的内存, 管理内存的策略, 我相信很多人都见过下面的枚举


屏幕快照 2016-06-21 上午11.34.32.png

当宿主对象被释放时,会根据指定的内存管理策略来处理管理对象. 如果指定的策略是assgin, 则宿主释放的时候, 关联对象不会被释放; 如果指定是retain或者copy, 当宿主对象释放时候, 关联对象也会被释放. 当然我们也可以考虑线程安全这个因素

屏幕快照 2016-06-21 下午1.41.26.png
屏幕快照 2016-06-21 下午1.41.12.png

首先,我们来看个例子, 如果我们创建一个UIButton对象, 会使用addTarget:这个方法添加action, 但是这么写太过于繁琐, 我们可以新建一个UIButton的分类, 给定一个block属性, 在该分类的.m文件中重写该属性的setter和getter方法, 首先setter方法中添加关联对象, 如果该对象已经有SEL方法, 先移除, 然后给self添加方法; 之后再getter方法中利用objc_getAssociatedObject(self, cvenies_btnActionKey)获取该属性,在利用Target...Action添加的方法中使用block, 则可以完成block回调需要处理的方法, 此后, 再创建UIButton对象之后, 可以直接利用buttonObject.blockBtnAction = ^(UIButton *sender) {}这个方法处理点击方法了.当然, 这只是runtime添加属性简单的实现, 也可以动态添加手势等属性, 根据自己的需要构建不同的分类.

2.Method Swizzling
首先,我们来了解一下Method Swizzling的定义, 所谓Method swizzling指的是改变一个已存在的选择器对应的实现的过程,它依赖于Objectvie-C中方法的调用能够在运行时进改变——通过改变类的调度表(dispatch table)中选择器到最终函数间的映射关系。
同样, 我们通过一个例子来引入Method Swizzling的用处, 对于一个大型的项目, 会有很多方向的部门并行开发, 而且很多大公司都在坚持敏捷开发的原则, 对于更新迭代很快的项目, 会存在很多的控制器, 当出现bug的时候, 可能会难以寻找代码所在的控制器, 这时候我们需要追踪定位页面所在的控制器, 会在viewWillAppear方法中添加 NSLog(@"当前控制器类名称:%@", [[self class] description]); 这样一段代码用于打印当前控制器的名字, 当然会用以下3种方法可供参考, 我们来逐条分析:
(1)最笨的方法, 在每个控制器的viewWillAppear中都添加 NSLog(@"当前控制器类名称:%@", [[self class] description]); 这样一段代码, 控制器中代码量会不断加重, 所以这是种最垃圾的处理方法;
(2)创建一个BaseViewController, 在BaseViewController的viewWillAppear方法中添加 NSLog(@"当前控制器类名称:%@", [[self class] description]); 这样一段代码, 所有项目中的控制器都继承自BaseViewController, 这是一种相对不错的方法
(3)最后我们来尝试一下Method Swizzling


屏幕快照 2016-06-21 下午2.51.22.png

使用Method Swizzling需要注意几点:
<1>Swizzling应该在+load方法中实现。
每个类的这两个方法会被Objective-C运行时系统自动调用,+load是在一个类最开始加载时调用,+initialize是在应用中第一次调用该类或它的实例的方式之前调用。这两个方法都是可选的,只有实现了才会被执行。

因为method swizzling会影响全局,所以减少冒险情况就很重要。+load能够保证在类初始化的时候就会被加载,这为改变系统行为提供了一些统一性。但+initialize并不能保证在什么时候被调用——事实上也有可能永远也不会被调用,例如应用程序从未直接的给该类发送消息。
<2>使用dispatch_once方法, 是为了保证该控制器只被创建一次.
使用Method Swizzling相对于上面的两种给人更加装逼的感觉, 当然我们知道Method Swizzling的具体实现才是最重要的.
关于Objective-C中runtime还有更多的黑魔法值得我们去探索, 一定要好好的研究底层的实现, 才是我们掌握一门语言的关键...

代码参考:https://github.com/CveniEs/CveniEsSchema.git

文章参考:南峰子的技术博客
CocoaChina/Method Swizzling专题

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

推荐阅读更多精彩内容