你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> 為對象添加一個釋放時觸發的block

為對象添加一個釋放時觸發的block

編輯:IOS開發基礎

有時我們需要在一個對象生命周期結束的時候觸發一個操作,希望當該對象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

#import @interface NSObject (Guard)
/**
 @brief 添加一個block,當該對象釋放時被調用
 **/
- (void)guard_addDeallocBlock:(void(^)(void))block;
@end

NSObject+Guard.m

#import "NSObject+Guard.h"
#import @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


  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved