libextobjc常用macro原理和使用

本文通过对libextobjc 常用macro的原理讲解, 使用后, 简化了开发过程中代码, 使一些问题在编译前被发现, 减少runtime crash的发生.

libextobjc介绍

ReactiveCocoa, Carthage的作者Justin Spahr Summers, 对“hobby”项目libextobjc进行开源; libextobjc是objc的一些拓展与宏的集合, 极大地方便了objc代码的编写, 减少了关于retainCycle和内存释放的bugs;

常用macro和keywords

  • @weakify 和 @strongify (ARC)
    两者成对使用, 主要解决了retainCycle问题; 使用方法如下:

    macro展开后的代码, 相当于注释中的简化代码;


通过两者的配合使用, 在block执行结束后, 红色线的capture就会断掉, 从而避免了retainCycle的出现;

  • @weakify 和 @strongify (MRC)
    MRC没有weak修饰, 改成__block即可;

  • @checkselector
    iOS自带的@selector, 没有检测作用, 即使selector对应的method没有实现, 也能编译, 导致runtime crash; @checkselector通过一个魔术般神奇的代码, 实现了编译前的方法检测, 减少了crash发生. 展开后的macro如图所示:

  • @keypath(…)
    将NSObject的property属性名字转成字符串, 同时进行编译前的检测, 避免了hard coding 字符串写错的现象, 提高维护性; 展开后, 如下:

@safecategory and @synthesizeAssociation

  • @safecategory 避免在Category中覆盖了系统方法, 如果名字相同, category里的method会被忽略.

  • @synthesizeAssociation
    简化在Category中添加property的步骤, 避免自定义key和使用objc_setAssocaitedObject等复杂方法, 但是不支持weak, BOOL, CGRect等property; 对下如下:

@onExit

先看一个场景:
-w1132

图中为了释放methodRet, 写了3次free, 中间一旦不小心提前return, 则造成了内存泄漏;

@onExit正式为了解决这个问题; 他能保证当methodRet变量超出作用域后, 能自动执行free代码, 从而简化了代码; 相当于Swift中的defer作用; 改写的代码:
-w1141

@onExit通过字符串拼接, 将block传递后变量的cleanup函数, 在变量超出作用域后, 执行这个函数(即Block). 展开后, 如下图所示:

Concrete Protocol

  • 为Protocol的方法提供默认的实现
  • 为已有的遵循同一个Protocol的ABC classes, 添加相同的方法;

  • 使用方法
    在正常的Protocol定义中使用@concrete关键字, 同时在m文件里, 对这个方法进行默认的实现;
    -w1120
本文如对你有帮助,请鼓励下!