美文网首页
iOS 自动释放的NSNotificationCenter

iOS 自动释放的NSNotificationCenter

作者: 杨柳小易 | 来源:发表于2018-01-15 19:46 被阅读128次

iOS 自动释放的NSNotificationCenter

借鉴与 <code>fbkvocontroller</code>自己实现一个自动释放的 NSNotificationCenter,

<code>fbkvocontroller</code> 是一个可以自动释放的kvo,并且提供了block 等方式。

具体实现如下:

@interface NSNotificationCenter(free)

- (void)pbtSafe_addObserver:(id)observer selector:(SEL)aSelector name:(NSNotificationName)aName object:(id)anObject;

@end

@interface PTVNotifitionToken : NSObject
@property (nonatomic, strong) NSString* token;
@property (nonatomic, strong) NSNotificationCenter *center;
@property (nonatomic, weak) id observe;
@end


@implementation PTVNotifitionToken

- (void)dealloc {
    
    if (self.center && self.token) {
        [self.center removeObserver:self.observe
                               name:self.token
                             object:nil];
    }
    
}

@end


@implementation NSNotificationCenter(free)

- (void)pbtSafe_addObserver:(id)observer selector:(SEL)aSelector name:(NSNotificationName)aName object:(id)anObject {
    PTVNotifitionToken *token = [PTVNotifitionToken new];
    token.center = self;
    token.token = aName;
    token.observe = observer;
    
    objc_setAssociatedObject(observer, aName.UTF8String, token, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    [self addObserver:observer
             selector:aSelector
                 name:aName object:anObject];
}

@end


原理非常简单,调用<code> pbtSafe_addObserver </code>的时候,动态的创建一个 PTVNotifitionToken,对象,通过关联 objc_setAssociatedObject ,给 observer,

我们知道,在自己的dealloc 函数调用之后会去释放和自己关联的obj,这样子就会调用 PTVNotifitionToken 的 dealloc 函数,然后调用 <code> removeObserver </code> 去释放。

方案②

static inline void BMP_EXChangeInstanceMethod(Class _originalClass ,SEL _originalSel,Class _targetClass ,SEL _targetSel){
    Method methodOriginal = class_getInstanceMethod(_originalClass, _originalSel);
    Method methodNew = class_getInstanceMethod(_targetClass, _targetSel);
    method_exchangeImplementations(methodOriginal, methodNew);
}

 BMP_EXChangeInstanceMethod([NSNotificationCenter class], @selector(addObserver:selector:name:object:), [NSNotificationCenter class], @selector(BMP_addObserver:selector:name:object:));
 BMP_EXChangeInstanceMethod([UIViewController class], NSSelectorFromString(@"dealloc"), [self class], NSSelectorFromString(@"BMP_dealloc"));

@implementation NSNotificationCenter (NotificationProtector)
- (void)BMP_addObserver:(id)observer selector:(SEL)aSelector name:(NSNotificationName)aName object:(id)anObject{
    objc_setAssociatedObject(observer, NSNotificationProtectorKey, NSNotificationProtectorValue, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    [self BMP_addObserver:observer selector:aSelector name:aName object:anObject];
}

@end

@implementation UIViewController (NotificationProtector)
- (void)BMP_dealloc{
    NSString *value = (NSString *)objc_getAssociatedObject(self, NSNotificationProtectorKey);
    if ([value isEqualToString:NSNotificationProtectorValue]) {
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }
    [self BMP_dealloc];
}

@end

阅读博客看到的,大致原理就是hook NSNotificationCenter 的方法,然后通过关联做一个标记,等到dealloc的时候判断一下是否有添加通知这样子!

END

考虑使用runtime 但是系统会调用很多次 addObserver 函数,会造成重复释放这种问题。

相关文章

  • iOS 自动释放的NSNotificationCenter

    iOS 自动释放的NSNotificationCenter 借鉴与 fbkvocontroller 自己实现一个...

  • NSNotificationCenter 使用

    1. NSNotificationCenter 简介 NSNotificationCenter 是 IOS 内部一...

  • 通知

    iOS中通知的使用NSNotificationCenter

  • Autorelease Pool

    自动释放池是iOS中的内存回收机制,能够延迟对象的释放。当池中的对象超出作用域后并不会立即被释放,等待自动释放池销...

  • NSNotificationCenter的通知名

    NSNotificationCenter的通知名(iOS7.0) 来自Github

  • 第一季:基础

    参考文章来源 腾讯社招iOS面试记录 1.谈谈你对自动释放池的理解, 1.自动释放池是OC提供的一种自动回收机制,...

  • 基础知识梳理

    iOS基础 1.mvc、mvvm iOS 关于MVC和MVVM设计模式的那些事 2.autoReless 自动释放...

  • autorelease 自动释放池的释放时机

    autorelease 自动释放池的释放时机 runloop就是iOS中的消息循环机制,当一个runloop结束时...

  • ios 自动释放池

    什么是自动释放池 OC中的一种内存自动回收机制,它可以延迟加入AutoreleasePool中的变量release...

  • iOS 自动释放池

    1.申明了一个对象__autoreleasepool 相当于调用了objc_autoreleasePoolPush...

网友评论

      本文标题:iOS 自动释放的NSNotificationCenter

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