zoukankan      html  css  js  c++  java
  • 改善系统的通知中心

    改善系统的通知中心

    iOS中的通知中心的实现实现机制是设计模式中的观察者.

    在不进行任何修改的情况下,通知中心是这么使用的.

    //
    //  NormalViewController.m
    //  NotificationCenter
    //
    //  Copyright (c) 2014年 Y.X. All rights reserved.
    //
    
    #import "NormalViewController.h"
    
    @interface NormalViewController ()
    
    @end
    
    @implementation NormalViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        // 注册通知中心
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(notificationEvent:)
                                                     name:NSStringFromClass([self class])
                                                   object:nil];
        
        // 发送消息
        [[NSNotificationCenter defaultCenter] postNotificationName:NSStringFromClass([self class])
                                                            object:nil
                                                          userInfo:@{@"name": @"YouXianMing"}];
        
        // 发送消息
        [[NSNotificationCenter defaultCenter] postNotificationName:NSStringFromClass([self class])
                                                            object:nil
                                                          userInfo:@{@"age": @"18"}];
    }
    
    - (void)notificationEvent:(id)sender
    {
        NSNotification *tmp = (NSNotification *)sender;
        NSLog(@"%@", tmp.userInfo);
    }
    
    - (void)dealloc
    {
        // 移除通知中心
        [[NSNotificationCenter defaultCenter] removeObserver:self
                                                        name:NSStringFromClass([self class])
                                                      object:nil];
    }
    
    @end

    没有对象的概念(都是通过类方法展示):

    获取数据部分还有点诡异:

    要将其修改到具备对象的概念,且使用起来更加人性化:)以下就是本人对齐进行的修改.

    NSObject+NotificationCenter.h   +   NSObject+NotificationCenter.m

    //
    //  NSObject+NotificationCenter.h
    //
    //  http://home.cnblogs.com/u/YouXianMing/
    //
    //  Copyright (c) 2014年 Y.X. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    #ifndef SELF_CLASS_NAME 
    #define SELF_CLASS_NAME   [self className]
    #endif
    
    @interface NSObject (NotificationCenter)
    
    @property (nonatomic, strong) NSString   *notificationName;  // 通知中心名字
    
    // 发送通知消息
    - (void)sendMessage:(NSDictionary *)obj toName:(NSString *)name;
    
    // 注册通知中心
    - (void)registerNotificationName:(NSString *)name selector:(SEL)selector;
    
    // 移除通知中心
    - (void)removeNotification:(NSString *)name;
    
    // 发送消息的对象
    - (id)messageObject;
    
    // 消息名字
    - (NSString *)messageName;
    
    // 当前对象名字
    + (NSString *)ClassName;
    - (NSString *)className;
    
    @end
    //
    //  NSObject+NotificationCenter.m
    //
    //  http://home.cnblogs.com/u/YouXianMing/
    //
    //  Copyright (c) 2014年 Y.X. All rights reserved.
    //
    
    #import "NSObject+NotificationCenter.h"
    #import <objc/runtime.h>
    
    @implementation NSObject (NotificationCenter)
    
    /* ================== 扩展了一个属性 ================== */
    static char notificationNameFlag;
    - (void)setNotificationName:(NSString *)notificationName
    {
        objc_setAssociatedObject(self, &notificationNameFlag,
                                 nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        objc_setAssociatedObject(self, &notificationNameFlag,
                                 notificationName,
                                 OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    - (NSString *)notificationName
    {
        return objc_getAssociatedObject(self, &notificationNameFlag);
    }
    /* ================== 扩展了一个属性 ================== */
    
    
    - (void)sendMessage:(NSDictionary *)obj toName:(NSString *)name
    {
        // 发送消息
        [[NSNotificationCenter defaultCenter] postNotificationName:name
                                                            object:nil
                                                          userInfo:obj];
    }
    
    - (void)registerNotificationName:(NSString *)name selector:(SEL)selector
    {
        // 如果没有提供名字,则用这个类的名字来注册
        if (name == nil)
        {
            [[NSNotificationCenter defaultCenter] addObserver:self
                                                     selector:selector
                                                         name:NSStringFromClass([self class])
                                                       object:nil];
        }
        else
        {
            [[NSNotificationCenter defaultCenter] addObserver:self
                                                     selector:selector
                                                         name:name
                                                       object:nil];
        }
    }
    
    - (void)removeNotification:(NSString *)name
    {
        // 如果没有提供名字,则用这个类的名字来移除(注意哦,此处需要与注册处的名字一致!)
        if (name == nil)
        {
            [[NSNotificationCenter defaultCenter] removeObserver:self
                                                            name:NSStringFromClass([self class])
                                                          object:nil];
        }
        else
        {
            [[NSNotificationCenter defaultCenter] removeObserver:self
                                                            name:name
                                                          object:nil];
        }
    }
    
    + (NSString *)ClassName
    {
        // 返回类名
        return NSStringFromClass(self);
    }
    
    - (NSString *)className
    {
        // 返回类名
        return NSStringFromClass([self class]);
    }
    
    - (id)messageObject
    {
        // 消息实体内容
        if ([self isKindOfClass:[NSNotification class]])
        {
            NSNotification *tmp = (NSNotification *)self;
            return tmp.userInfo;
        }
        else
        {
            return nil;
        }
    }
    
    - (NSString *)messageName
    {
        // 注册消息者的名字
        if ([self isKindOfClass:[NSNotification class]])
        {
            NSNotification *tmp = (NSNotification *)self;
            return tmp.name;
        }
        else
        {
            return nil;
        }
    }
    
    @end

    使用时的代码如下:

    //
    //  RootViewController.m
    //  NotificationCenter
    //
    //  Copyright (c) 2014年 Y.X. All rights reserved.
    //
    
    #import "RootViewController.h"
    #import "NSObject+NotificationCenter.h"
    
    @interface RootViewController ()
    
    @end
    
    @implementation RootViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        
        // 注册通知中心
        [self registerNotificationName:[self className]
                              selector:@selector(notificationEvent:)];
        
        // 对象A发送通知
        [@"A" sendMessage:@{@"name": @"YouXianMing"}
                   toName:[self className]];
        
        // 对象B发送通知
        [@"B" sendMessage:@{@"age": @"18"}
                   toName:[self className]];
    }
    
    - (void)notificationEvent:(id)sender
    {
        // 获取到message
        id object = [sender messageObject];
        
        // 打印message
        NSLog(@"%@", object);
    }
    
    - (void)dealloc
    {
        // 移除注册的通知中心
        [self removeNotification:[self className]];
    }
    
    @end

    至少,我们减少了认知上面得差异,不需要你知道有通知中心这个东西存在了,取数据也有专门的方法直接获取.

    其实,我还扩展了一个NSObject的一个属性,这个属性就是用来标示被注册通知中心名字的,以下展示的是高级用法.

    创建Student的Model

    //
    //  Student.h
    //  NotificationCenter
    //
    //  Copyright (c) 2014年 Y.X. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    @interface Student : NSObject
    
    @property (nonatomic, strong) NSString *name;
    
    @end
    //
    //  Student.m
    //  NotificationCenter
    //
    //  Copyright (c) 2014年 Y.X. All rights reserved.
    //
    
    #import "Student.h"
    #import "NSObject+NotificationCenter.h"
    
    @implementation Student
    
    @synthesize name = _name;
    - (void)setName:(NSString *)name
    {
        _name = name;
        
        if (self.notificationName)
        {
            [self sendMessage:@{@"data": name} toName:self.notificationName];
        }
    }
    - (NSString *)name
    {
        return _name;
    }
    
    @end

    使用:

    //
    //  RootViewController.m
    //  NotificationCenter
    //
    //  Copyright (c) 2014年 Y.X. All rights reserved.
    //
    
    #import "RootViewController.h"
    #import "NSObject+NotificationCenter.h"
    #import "Student.h"
    
    @interface RootViewController ()
    
    @end
    
    @implementation RootViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        
        // 注册通知中心
        [self registerNotificationName:[self className]
                              selector:@selector(notificationEvent:)];
        
    
        Student *stu         = [Student new];
        stu.notificationName = [self className];
        stu.name             = @"YouXianMing";
    }
    
    - (void)notificationEvent:(id)sender
    {
        // 获取到message
        id object = [sender messageObject];
        
        // 打印message
        NSLog(@"%@", object);
    }
    
    - (void)dealloc
    {
        // 移除注册的通知中心
        [self removeNotification:[self className]];
    }
    
    @end

    其实,这已经从"不记名字"的通知中心转变成了"记名"的通知中心了,使用起来也是非常简单的:)

  • 相关阅读:
    6.Docker中上传镜像到docker hub中
    altermanager使用报错
    Grafana官方和社区提供的dashboard
    什么是 云原生?
    prometheus被OOM杀死
    新版GRANAFA K8S插件 K8S NODE 图表不显示问题解决方法
    python2和python3的不同
    一次使用Python连接数据库生成二维码并安装为windows服务的工作任务
    Python连接oracle
    numpy.ndarray的赋值操作
  • 原文地址:https://www.cnblogs.com/YouXianMing/p/3902392.html
Copyright © 2011-2022 走看看