改善系统的通知中心
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
其实,这已经从"不记名字"的通知中心转变成了"记名"的通知中心了,使用起来也是非常简单的:)
时间: 2024-08-30 18:54:41