zoukankan      html  css  js  c++  java
  • 为对象添加一个释放时触发的block

    有时我们需要在一个对象生命周期结束的时候触发一个操作,希望当该对象dealloc的时候调用一个外部指定的block,但又不希望直接hook dealloc方法,这样侵入性太强了.下面贴一段非常简单的实现方式,通过一个category给外部暴露一个block注入的接口,内部将该block封装到一个寄生对象中(Parasite),该寄生对象在dealoc的时候触发block调用,所有的寄生对象通过runtime的AssociatedObject机制与宿主共存亡,从而达到监控宿主生命周期的目的.

    注意事项

    • block触发的线程与对象释放时的线程一致,请注意后续操作的线程安全.
    • 不要在block中强引用对象,否则引用循环释放不了;
    • 不要在block中通过weak引用对象,因为此时会返回nil;
      (根据WWDC2011,Session322对对象释放时间的描述,associated objects清除在对象生命周期中很晚才执行,通过被NSObject -dealloc方法调用的object_dispose()函数完成);

    NSObject+Guard.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #import <Foundation/Foundation.h>

    @interface NSObject (Guard)

    /**
    @brief 添加一个block,当该对象释放时被调用
    **/
    - (void)guard_addDeallocBlock:(void(^)(void))block;

    @end

    NSObject+Guard.m

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    #import "NSObject+Guard.h"
    #import <objc/runtime.h>

    @interface Parasite : NSObject
    @property (nonatomic, copy) void(^deallocBlock)(void);
    @end

    @implementation Parasite

    - (void)dealloc {
    if (self.deallocBlock) {
    self.deallocBlock();
    }
    }

    @end

    @implementation NSObject (Guard)

    - (void)guard_addDeallocBlock:(void(^)(void))block {
    @synchronized (self) {
    static NSString *kAssociatedKey = nil;
    NSMutableArray *parasiteList = objc_getAssociatedObject(self, &kAssociatedKey);
    if (!parasiteList) {
    parasiteList = [NSMutableArray new];
    objc_setAssociatedObject(self, &kAssociatedKey, parasiteList, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    Parasite *parasite = [Parasite new];
    parasite.deallocBlock = block;
    [parasiteList addObject: parasite];
    }
    }

    @end
  • 相关阅读:
    layui第三方组件运用
    layui select lay-filter就不渲染和全局渲染用法和校验
    layui 点击操作列后背景色去掉
    layui混合案列问题
    使用layui富文本添加日志内容,并获取子窗体的富文本内容
    layu tab切换table
    layui 父窗体传子窗体select动态选中
    jstl过长的内容处理空格以及换行并通过js处理内容自动换行
    js中运用jstl标签解决checked是否选中等问题
    javaMD5实现加密解密
  • 原文地址:https://www.cnblogs.com/xiao-love-meng/p/5757560.html
Copyright © 2011-2022 走看看