通过OC-Runtime间接注入 dealloc 代码

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

    // 为了在对象销毁时触发一些动作,不得不继承对象,然后实现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释放完关联对象后自身也进入销毁动作,实现了两个对象的同生共死.

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

你可能感兴趣的:(通过OC-Runtime间接注入 dealloc 代码)