改善系统的通知中心
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, ¬ificationNameFlag, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC); objc_setAssociatedObject(self, ¬ificationNameFlag, notificationName, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - (NSString *)notificationName { return objc_getAssociatedObject(self, ¬ificationNameFlag); } /* ================== 扩展了一个属性 ================== */ - (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
其实,这已经从"不记名字"的通知中心转变成了"记名"的通知中心了,使用起来也是非常简单的:)