先看一个情景(如果你没有类似的应用情景,就不用往下看啦,_)
// 为了在对象销毁时触发一些动作,不得不继承对象,然后实现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释放完关联对象后自身也进入销毁动作,实现了两个对象的同生共死.
有些疑问,这东西有什么用? 有些时候您想知道一个系统对象是什么时候释放的话,这东西就能派上用场了~~~ _