首页 > 代码库 > 重写通知中心类

重写通知中心类

重写通知中心类

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

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. 使用时注意要将协议的方法实现了