重写通知中心类

简介:

重写通知中心类

笔者重新设计了通知中心类,功能完全与系统的通知中心一致,但有着比系统通知中心更优秀的地方:

1. 注册了通知中心不需要手动移除,如果注册对象自动释放了,在通知中心中注册的信息也会自动消失

2. 传递的参数可以是任何的对象,包括数组,字典等等一切对象

3. 基于NSObject的category扩展而来,使用非常的方便

所有的源码如下:

CustumNotification.h

//
//  CustumNotification.h
//
//  http://home.cnblogs.com/u/YouXianMing/
//
//  Copyright (c) 2014年 Y.X. All rights reserved.
//

#import <Foundation/Foundation.h>

@protocol CustomNotificationProtrol <NSObject>

@optional
- (void)listenCustumNotificationEvent:(id)message;
- (void)listenCustumNotificationEvent:(id)message messageFlag:(id)flag;

@end

SuperNotification.h   与   SuperNotification.m
//
//  SuperNotification.h
//
//  http://home.cnblogs.com/u/YouXianMing/
//
//  Copyright (c) 2014年 Y.X. All rights reserved.
//

#import <Foundation/Foundation.h>
@protocol CustomNotificationProtrol;

@interface SuperNotification : NSObject

+ (void)delegate:(id<CustomNotificationProtrol>)target name:(NSString *)name;

+ (void)message:(id)msg toName:(NSString *)name;
+ (void)message:(id)msg messageFlag:(id)flag toName:(NSString *)name;

+ (void)remove:(id<CustomNotificationProtrol>)target name:(NSString *)name;

+ (id)objectByName:(NSString *)name;
+ (NSString *)nameByObject:(id)obj;

@end


//
//  SuperNotification.m
//
//  http://home.cnblogs.com/u/YouXianMing/
//
//  Copyright (c) 2014年 Y.X. All rights reserved.
//
#import "SuperNotification.h"
#import "CustomNotificationProtrol.h"

static NSMapTable  *weakNotification = nil;

@implementation SuperNotification

+ (void)initialize
{
    if (self == [SuperNotification class])
    {
        // 强引用key值弱引用object(key值不会被释放)
        weakNotification = [NSMapTable strongToWeakObjectsMapTable];
    }
}

+ (void)delegate:(id<CustomNotificationProtrol>)target name:(NSString *)name
{
    // 将对象添加进weak字典
    if ([weakNotification objectForKey:name] == nil)
    {
        // 添加对象进weak集合
        [weakNotification setObject:target forKey:name];
    }
}

+ (void)message:(id)msg toName:(NSString *)name
{
    // 如果name以及source为空
    if (name == nil)
    {
        return;
    }
    
    // 获取抽象类
    id<CustomNotificationProtrol> object = [weakNotification objectForKey:name];
    if (object == nil)
    {
        // 没有根据键值找到对象(没有添加对象或者对象已经被释放了),则移除掉这个键值
        [weakNotification removeObjectForKey:name];
    }
    else
    {
        // 判断抽象类能否执行方法
        if ([object respondsToSelector:@selector(listenCustumNotificationEvent:)] == YES)
        {
            // 能执行方法则执行这个方法
            [object listenCustumNotificationEvent:msg];
        }
    }
}

+ (void)message:(id)msg messageFlag:(id)flag toName:(NSString *)name
{
    // 如果name以及source为空
    if (name == nil && flag == nil)
    {
        return;
    }
    
    // 获取抽象类
    id<CustomNotificationProtrol> object = [weakNotification objectForKey:name];
    if (object == nil)
    {
        // 没有根据键值找到对象(没有添加对象或者对象已经被释放了),则移除掉这个键值
        [weakNotification removeObjectForKey:name];
    }
    else
    {
        // 判断抽象类能否执行方法
        if ([object respondsToSelector:@selector(listenCustumNotificationEvent:messageFlag:)] == YES)
        {
            // 能执行方法则执行这个方法
            [object listenCustumNotificationEvent:msg messageFlag:flag];
        }
    }
}

+ (void)remove:(id<CustomNotificationProtrol>)target name:(NSString *)name
{
    if (target == nil || name == nil)
    {
        return;
    }
    
    // 移除掉键值
    [weakNotification removeObjectForKey:name];
}

+ (id)objectByName:(NSString *)name
{
    return [weakNotification objectForKey:name];
}

+ (NSString *)nameByObject:(id)obj
{
    NSString *myKey = nil;
    
    // 获取所有key值
    NSEnumerator * enu = [weakNotification keyEnumerator];

    // 遍历key值
    NSString *key = nil;
    while (key = [enu nextObject])
    {
        // 根据key值取出对象
        id tmpObj = [weakNotification objectForKey:key];
        
        // 比较对象
        if ([tmpObj isEqual:obj])
        {
            myKey = key;
            break;
        }
    }
    
    return myKey;
}

@end

NSObject+CustomNotification.h  与  NSObject+CustomNotification.m
//
//  NSObject+CustomNotification.h
//
//  http://home.cnblogs.com/u/YouXianMing/
//
//  Copyright (c) 2014年 Y.X. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "CustomNotificationProtrol.h"

/*
 个人定制的通知中心是需要实现以下两个方法你才能接受到通知
 
 - (void)listenCustumNotificationEvent:(id)message;
 - (void)listenCustumNotificationEvent:(id)message messageFlag:(id)flag;
 
 */

@interface NSObject (CustomNotification)

@property (nonatomic, strong) NSString *custumNotificationName;

- (void)registerCustomNotificationByName:(NSString *)name;
- (void)sendMessage:(id)msg toName:(NSString *)name;
- (void)sendMessage:(id)msg messageFlag:(id)flag toName:(NSString *)name;
- (void)removeCustomNotificationByName:(NSString *)name;
- (NSString *)getRegisterNotificationName;

+ (NSString *)ClassName;
- (NSString *)className;

@end


//
//  NSObject+CustomNotification.m
//
//  http://home.cnblogs.com/u/YouXianMing/
//
//  Copyright (c) 2014年 Y.X. All rights reserved.
//


#import "NSObject+CustomNotification.h"
#import "SuperNotification.h"
#import <objc/runtime.h>

@interface NSObject ()<CustomNotificationProtrol>

@property (nonatomic, assign) id<CustomNotificationProtrol> customNotificationProtrolDelegate;

@end

@implementation NSObject (CustomNotification)

static char customNotificationProtrolDelegateFlag;
- (void)setCustomNotificationProtrolDelegate:(id<CustomNotificationProtrol>)customNotificationProtrolDelegate
{
        objc_setAssociatedObject(self, &customNotificationProtrolDelegateFlag,
                                 nil, OBJC_ASSOCIATION_ASSIGN);
        objc_setAssociatedObject(self, &customNotificationProtrolDelegateFlag,
                                 customNotificationProtrolDelegate,
                                 OBJC_ASSOCIATION_ASSIGN);
}
- (id<CustomNotificationProtrol>)customNotificationProtrolDelegate
{
    return objc_getAssociatedObject(self, &customNotificationProtrolDelegateFlag);
}

static char customNotificationNameFlag;
- (void)setCustumNotificationName:(NSString *)custumNotificationName
{
    objc_setAssociatedObject(self, &customNotificationNameFlag,
                             nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    objc_setAssociatedObject(self, &customNotificationNameFlag,
                             custumNotificationName,
                             OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSString *)custumNotificationName
{
    return objc_getAssociatedObject(self, &customNotificationNameFlag);
}





- (void)registerCustomNotificationByName:(NSString *)name
{
    // 将自己设置成为代理
    self.customNotificationProtrolDelegate = self;
    
    if (name == nil)
    {
        [SuperNotification delegate:self.customNotificationProtrolDelegate
                               name:NSStringFromClass([self class])];
    }
    else
    {
        [SuperNotification delegate:self.customNotificationProtrolDelegate
                               name:name];
    }
}

- (void)sendMessage:(id)msg toName:(NSString *)name
{
    [SuperNotification message:msg
                        toName:name];
}

- (void)sendMessage:(id)msg messageFlag:(id)flag toName:(NSString *)name
{
    [SuperNotification message:msg
                   messageFlag:flag
                        toName:name];
}

- (void)removeCustomNotificationByName:(NSString *)name
{
    if (name == nil)
    {
        [SuperNotification remove:self.customNotificationProtrolDelegate
                             name:NSStringFromClass([self class])];
    }
    else
    {
        [SuperNotification remove:self.customNotificationProtrolDelegate
                             name:name];
    }
}

- (NSString *)getRegisterNotificationName
{
    return [SuperNotification nameByObject:self];
}

+ (NSString *)ClassName
{
    // 返回类名
    return NSStringFromClass(self);
}

- (NSString *)className
{
    // 返回类名
    return NSStringFromClass([self class]);
}

@end

以下是使用源码:
//
//  RootViewController.m
//  SuperNotification
//
//  Copyright (c) 2014年 Y.X. All rights reserved.
//

#import "RootViewController.h"
#import "NSObject+CustomNotification.h"

@interface RootViewController ()

@end

@implementation RootViewController


- (void)viewDidLoad
{
    [super viewDidLoad];

    // 注册通知中心
    [self registerCustomNotificationByName:nil];
    
    // 发送通知信息(任意对象都可以发布通知信息)
    [@"YouXianMing" sendMessage:@[@"YouXianMing", @"YouHongMing"]
                    messageFlag:[@"YouXianMing" className]
                         toName:[self className]];
}

// 监听通知信息
- (void)listenCustumNotificationEvent:(id)message messageFlag:(id)flag
{
    NSLog(@"%@ - %@", flag, message);
}

@end

以下简短的说一下设计细节:

1. 协议文件是一个单独的文件

2. 协议对象可以看做一个对象

3. runtime支持协议对象的category的扩展

4. category中奖对象自己设置成代理

5. 使用时注意要将协议的方法实现了

目录
相关文章
|
API 对象存储
腾讯云对象存储cos获取图片像素信息
简述获取图片像素信息的几种方案
腾讯云对象存储cos获取图片像素信息
|
11月前
|
机器学习/深度学习 传感器 运维
使用机器学习技术进行时间序列缺失数据填充:基础方法与入门案例
本文探讨了时间序列分析中数据缺失的问题,并通过实际案例展示了如何利用机器学习技术进行缺失值补充。文章构建了一个模拟的能源生产数据集,采用线性回归和决策树回归两种方法进行缺失值补充,并从统计特征、自相关性、趋势和季节性等多个维度进行了详细评估。结果显示,决策树方法在处理复杂非线性模式和保持数据局部特征方面表现更佳,而线性回归方法则适用于简单的线性趋势数据。文章最后总结了两种方法的优劣,并给出了实际应用建议。
543 7
使用机器学习技术进行时间序列缺失数据填充:基础方法与入门案例
|
11月前
|
监控 关系型数据库 MySQL
Flink CDC MySQL同步MySQL错误记录
在使用Flink CDC同步MySQL数据时,常见的错误包括连接错误、权限错误、表结构变化、数据类型不匹配、主键冲突和
420 17
|
12月前
|
存储 算法 Linux
数据恢复软件恢复的数据打不开的原因与解决方法
数据恢复软件恢复的数据打不开的原因与解决方法
2059 10
|
机器学习/深度学习 人工智能 自然语言处理
【AI大模型】LLM主流开源大模型介绍
【AI大模型】LLM主流开源大模型介绍
|
网络协议 应用服务中间件 网络安全
阿里云轻量应用服务器的使用限制
阿里云轻量应用服务器的使用限制
|
机器学习/深度学习 资源调度 自动驾驶
OFDM:赋能5G通信的基石
OFDM:赋能5G通信的基石
1034 3
|
存储 算法 固态存储
EMMC和Nand是不是还傻傻分不清楚
EMMC和Nand是不是还傻傻分不清楚
2158 0
|
新零售 人工智能 供应链
大咖说|试衣到家 CEO:我们卖的不是衣服,是服务
一千个人心中就有一千个时尚界的哈姆雷特,随着时代发展,消费者对时尚的理解和鉴赏能力正逐步提升,对时尚的态度也越来越个性化,更注重体验感与尊贵感。
440 0
大咖说|试衣到家 CEO:我们卖的不是衣服,是服务
|
存储 人工智能 并行计算
超算简史与下一代超级计算机
为啥你叫超级计算机,别人只能叫普通计算机? 因为我兄弟多,个头大,能力强呀!
6534 0
超算简史与下一代超级计算机
下一篇
开通oss服务