美文网首页
在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