美文网首页
iOS-简单实现NSNotificationCenter

iOS-简单实现NSNotificationCenter

作者: 大风车__ | 来源:发表于2019-07-23 16:29 被阅读0次

    1. h文件

    #import <Foundation/Foundation.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface NotificationCenter : NSObject
    
    - (instancetype)init UNAVAILABLE_ATTRIBUTE;
    + (instancetype)new UNAVAILABLE_ATTRIBUTE;
    
    @property (class, readonly, strong) NotificationCenter *defaultCenter;
    
    - (void)addObserver:(id)observer selector:(SEL)aSelector name:(nullable NSNotificationName)aName object:(nullable id)anObject;
    
    - (void)postNotification:(NSNotification *)notification;
    - (void)postNotificationName:(NSNotificationName)aName object:(nullable id)anObject;
    - (void)postNotificationName:(NSNotificationName)aName object:(nullable id)anObject userInfo:(nullable NSDictionary *)aUserInfo;
    
    - (void)removeObserver:(id)observer;
    - (void)removeObserver:(id)observer name:(nullable NSNotificationName)aName object:(nullable id)anObject;
    
    @end
    
    NS_ASSUME_NONNULL_END
    

    2. m文件

    #import "NotificationCenter.h"
    #import <objc/message.h>
    
    static NotificationCenter *shareInstance = nil;
    
    @interface ObserverInfo: NSObject
    @property(nonatomic, assign) SEL selector;
    @property(nonatomic, weak) id observer;
    @property(nonatomic, strong) NSNotification *notification;
    @end
    
    @implementation ObserverInfo
    @end
    
    @interface NotificationCenter()
    @property(nonatomic, strong) NSMutableArray<ObserverInfo *> *observers;
    @end
    
    @implementation NotificationCenter
    
    - (void)addObserver:(id)observer selector:(SEL)aSelector name:(NSNotificationName)aName object:(id)anObject{
        if (!observer || !aSelector) {
            return;
        }
        NSNotification *notification = [NSNotification notificationWithName:aName object:anObject];
        ObserverInfo *info = [ObserverInfo new];
        info.notification = notification;
        info.observer = observer;
        info.selector = aSelector;
        [_observers addObject:info];
    }
    
    - (void)postNotificationName:(NSNotificationName)aName object:(id)anObject{
        NSNotification *notification = [NSNotification notificationWithName:aName object:anObject];
        [self postNotification:notification];
    }
    
    - (void)postNotificationName:(NSNotificationName)aName object:(id)anObject userInfo:(NSDictionary *)aUserInfo{
        NSNotification *notification = [NSNotification notificationWithName:aName object:anObject userInfo:aUserInfo];
        [self postNotification:notification];
    }
    
    - (void)postNotification:(NSNotification *)notification{
        if (!notification){
            return;
        }
        [_observers enumerateObjectsUsingBlock:^(ObserverInfo * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            if ([notification.name isEqualToString:obj.notification.name]){
                if (notification.object){
                    ((void (*)(id, SEL, id))(void *) objc_msgSend)(obj.observer, obj.selector, notification);
                }else{
                    NSNotification *aNotification = [NSNotification notificationWithName:notification.name object:obj.notification.object userInfo:notification.userInfo];
                    ((void (*)(id, SEL, id))(void *) objc_msgSend)(obj.observer, obj.selector, aNotification);
                }
            }
        }];
    }
    
    - (void)removeObserver:(id)observer name:(NSNotificationName)aName object:(id)anObject{
        if(!observer){
            return;
        }
        [_observers enumerateObjectsUsingBlock:^(ObserverInfo * _Nonnull obj, NSUInteger idx,  BOOL * _Nonnull stop) {
            NSNotification *notification = obj.notification;
            if(obj.observer == observer
               && notification.object == anObject
               && [notification.name isEqualToString:aName]){
                [self.observers removeObject:obj];
            }
        }];
    }
    
    - (void)removeObserver:(id)observer{
        if(!observer){
            return;
        }
        [_observers enumerateObjectsUsingBlock:^(ObserverInfo * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            if(obj.observer == observer){
                [self.observers removeObject:obj];
            }
        }];
    }
    
    + (NotificationCenter *)defaultCenter{
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            shareInstance = [[self alloc]init];
            shareInstance.observers = [NSMutableArray new];
        });
        return shareInstance;
    }
    @end
    

    3. 使用

    #import "ViewController.h"
    #import "NotificationCenter.h"
    
    static NSString * const NotificationName = @"NotificationName";
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        UIButton *add = [[UIButton alloc]init];
        add.frame = CGRectMake(100, 100, 100, 50);
        [add setTitle:@"添加通知" forState:UIControlStateNormal];
        [add setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        [add addTarget:self action:@selector(addClicked:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:add];
        
        UIButton *send = [[UIButton alloc]init];
        send.frame = CGRectMake(100, 150, 100, 50);
        [send setTitle:@"发送通知" forState:UIControlStateNormal];
        [send setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        [send addTarget:self action:@selector(sendClicked:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:send];
        
        UIButton *delete = [[UIButton alloc]init];
        delete.frame = CGRectMake(100, 200, 100, 50);
        [delete setTitle:@"移除通知" forState:UIControlStateNormal];
        [delete setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        [delete addTarget:self action:@selector(deleteClicked:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:delete];
    }
    
    - (void)addClicked:(id)sender{
        [[NotificationCenter defaultCenter] addObserver:self selector:@selector(respondsToNotification:) name:NotificationName object:nil];
    }
    
    - (void)sendClicked:(id)sender{
        [[NotificationCenter defaultCenter] postNotificationName:NotificationName object:@"数据"];
    }
    
    - (void)deleteClicked:(id)sender{
        [[NotificationCenter defaultCenter] removeObserver:self];
    }
    
    - (void)respondsToNotification:(NSNotification *)aNotification{
        NSLog(@"%@", aNotification.object);
    }
    @end
    

    相关文章

      网友评论

          本文标题:iOS-简单实现NSNotificationCenter

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