通过Runtime间接注入 dealloc 代码

来源:互联网 发布:手机围棋记谱软件 编辑:程序博客网 时间:2024/06/06 03:02

  先看一个情景(如果你没有类似的应用情景,就不用往下看啦,^_^)

    // 为了在对象销毁时触发一些动作,不得不继承对象,然后实现Dealloc方法    @interface SCView : UIView    @end    @implementation SCView    - (void)dealloc    {    // do sth.............    }    @end

  继承一个类并不是什么大事情, 但有些对象是别人创建好的,你没法换成别的类,而且就为了一个Dealloc继承过来太麻烦了,借助运行时(Runtime),这情景可以很简单的解决.

  首先我不提倡使用 method_exchangeImplementations 这种过于暴力而且缺乏美感的做法,我想说的是另一种思路--共生对象,什么是共生对象? 就是两个对象的生存周期是一样的(或者作用周期可以等效),通过操作其中一个对象,实现对另一个对象的干预,方法如下.

  首先创建一个NSObject对象(越小的对象越好,因为只是作为一个寄宿体),然后在Dealloc方法中调用一个Block,大概就是这个样子

    // 声明一个无参数的Block类型    typedef void(^EmptyBlock)();    @interface SCBlock : NSObject    // 只需暴露一个setBlock方法    - (void)setDeallocBlock:(EmptyBlock)deallocBlock;    @end    // 然后实现功能    @implementation SCBlock    {        EmptyBlock  _deallocBlock;    }    - (void)dealloc    {          if (_deallocBlock) _deallocBlock();    }    - (void)setDeallocBlock:(EmptyBlock)deallocBlock    {          _deallocBlock = deallocBlock;    }    @end      好,到这里已经完成一半了,接下来做另一半.      现在创建了一个"共生"类出来,但还没有任何使用,通过强大的运行时把他们的生命关联起来    SCBlock *v1 = [[SCBlock alloc] init];    [v1 setDeallocBlock:^{    // do sth........    }];    // 核心,关键,重要!    void *ptr = ((__bridge void *)v1);    // v1对象必须只能由object持有,使用时注意!    objc_setAssociatedObject(object, ptr, v1, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

  你没看错,就是添加一个关联对象,object是要共生的对象(可以是任意对象),v1是我们可以操作的对象,因为对象在销毁时一定会先释放关联对象,由于v1只有共生对象持有,所以释放后v1销毁,触发Block动作,object释放完关联对象后自身也进入销毁动作,实现了两个对象的同生共死.

  有些疑问,这东西有什么用? 有些时候您想知道一个系统对象是什么时候释放的话,这东西就能派上用场了~~~ ^_^

0 0
原创粉丝点击