美文网首页
在category中实现dealloc要执行的代码

在category中实现dealloc要执行的代码

作者: 黑糊糊的梦想家 | 来源:发表于2019-07-16 17:38 被阅读0次

    问题:

    给类添加category方法时,如果方法名与原类中的方法重名是会‘覆盖’原类的方法(不是真正意义上的覆盖,category方法会添加到方法列表前面)。如果我们想在category中放入一些本该放在dealloc方法中执行的代码,直接在分类里实现dealloc方法显然是不行的,这会对原类本就实现过的dealloc方法造成影响,如果不想动原类中的代码,要怎么实现这个需求?

    实现思路:

    给类关联一个对象,这个对象是我们自己创建的中间对象。当类创建的实例对象释放时,这个关联对象也会释放,此时关联对象就会执行自己的dealloc方法。如果我们把分类中要执行的dealloc代码放到这个关联属性的block中,让这个关联属性在执行dealloc时执行这个block,这样就达到我们想要达到的目的。

    上代码

    首先是创建中间类:

    #import <Foundation/Foundation.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface TmpObject : NSObject
    
    + (instancetype)objWithDeallocBlock:(void(^)(void))deallocBlock;
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    
    #import "TmpObject.h"
    @interface TmpObject ()
    @property (nonatomic, copy ) void(^deallocBlock)(void);
    @end
    
    @implementation TmpObject
    
    - (instancetype)initWithDellocBlock:(void(^)(void))dellocBlock
    {
        self = [super init];
        if (self) {
            _deallocBlock = dellocBlock;
        }
        return self;
    }
    
    + (instancetype)objWithDeallocBlock:(void(^)(void))deallocBlock{
        return [[self alloc] initWithDellocBlock:deallocBlock];
    }
    
    - (void)dealloc{
        !self.deallocBlock?:self.deallocBlock();
    }
    
    @end
    
    

    分类中的实现(这里给UIView添加分类,在UIView的分类中实现皮肤主题切换的监听功能,需要在view释放时移除消息监听):

    #import <UIKit/UIKit.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface UIView (LLThemeAdd)
    
    - (void)addThemeDidChangedNotification;
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    #import "UIView+LLThemeAdd.h"
    #import "TmpObject.h"
    #import <objc/runtime.h>
    @implementation UIView (LLThemeAdd)
    
    static const char kThemeTmpObjKey = '\0';
    
    - (void)addThemeDidChangedNotification{
        __weak typeof (self)weakSelf = self;
        TmpObject *tmpObj = [TmpObject objWithDeallocBlock:^{
            [[NSNotificationCenter defaultCenter] removeObserver:weakSelf];
        }];
        objc_setAssociatedObject(self, &kThemeTmpObjKey, tmpObj, OBJC_ASSOCIATION_RETAIN);
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(themeChanged:) name:@"kThemeDidChangedNotification" object:nil];
    }
    
    - (void)themeChanged:(NSNotification *)notification{
        NSLog(@"++++++ ThemeDidChanged");
    }
    
    @end
    
    

    相关文章

      网友评论

          本文标题:在category中实现dealloc要执行的代码

          本文链接:https://www.haomeiwen.com/subject/agwtlctx.html