自定义通知
Posted 「违规用户」
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义通知相关的知识,希望对你有一定的参考价值。
我们在做项目时:
当某个地方改变(从服务端接收数据)需要通知2个及以上的地方(view,viewController,manager等任何一个对象)时,我们就应该考虑使用通知。
一般项目用到通知的地方有,登陆,定位,XMPP,APP前后台切换。
在实现通知时:我们首先要明白谁要通知谁,谁注册,谁发送,谁接受处理。
1.Manager 监听 VC
XMPP用来做收消息时,我们需要做一些事情,比如更改VC的界面。那么这个时候,VC就是需要被观察的对象。那么谁是观察者呢?我们可以单纯为XMPP来做一个Manager类。用它来做观察者。这样这个Manager类可以做为观察这个VC一些准备,如验证,登陆,连接,断开,收到消息POST到这个VC,这个时候的业务处理你可以在Manager也可以在VC中。当然,通知是一对多的,也就是我一个Manager类可以观察很多个VC,那么这个时候我们可以在Manager中私有一个数组用以保存需要观察的对象。这样Manager当收到服务端消息时,我们可以根据情况找到VC发送通知。我们可以在manager类中定义一组协议,让每个VC实现去选择实现。其实需不需要实现协议无关紧要,只要VC中实现了某个方法就好。到这里,你可能会发现压根没有用到通知,是的,这是模仿通知写的。我想系统的通知原理也就是这样吧。
2.Manager 监听Manager
对于登陆,我们也可以根据1来新建一个Manager,用来观察登陆登出时处理VC,如调出登陆界面等。但是如果一个用户退出了,这个时候我们还需要xmpp吗?或者需要xmpp返回的一些跟用户有关的消息吗?当然不需要。那么这个时候,UserManager就是观察者,XMPPManager就是被观察者,当用户退出时,UserManager就可以发送通知给XMPPManager让其关掉XMPP连接等操作。
3.延伸
当APP前后台切换时,需要对XMPP,Location(定位)做一些变化,如进入后台时,断开XMPP,停止定位,进入前台,连接XMPP,开启定位。我们怎么做,在Manager类暴露相应方法,然后在入口类写相应的代码?但是由于我们把XMPP,Location(定位)相关的业务封装到各自Manager中,这样我们就可以通过通知来叫相应的Manager类做处理。具体做法:
(1)定义一套协议跟前后台切换通知一一对应。
@protocol MKEnvObserverApplicationProtocol <NSObject>
@optional
- (void)mkEnvObserverApplicationDidEnterBackground:(NSNotification *)notification;
- (void)mkEnvObserverApplicationWillEnterForeground:(NSNotification *)notification;
- (void)mkEnvObserverApplicationDidFinishLaunching:(NSNotification *)notification;
- (void)mkEnvObserverApplicationDidBecomeActive:(NSNotification *)notification;
- (void)mkEnvObserverApplicationWillResignActive:(NSNotification *)notification;
- (void)mkEnvObserverApplicationDidReceiveMemoryWarning:(NSNotification *)notification;
- (void)mkEnvObserverApplicationWillTerminate:(NSNotification *)notification;
- (void)mkEnvObserverApplicationSignificantTimeChange:(NSNotification *)notification;
- (void)mkEnvObserverApplicationWillChangeStatusBarOrientation:(NSNotification *)notification;
- (void)mkEnvObserverApplicationDidChangeStatusBarOrientation:(NSNotification *)notification;
- (void)mkEnvObserverApplicationStatusBarOrientationUserInfoKey:(NSNotification *)notification;
- (void)mkEnvObserverApplicationWillChangeStatusBarFrame:(NSNotification *)notification;
- (void)mkEnvObserverApplicationDidChangeStatusBarFrame:(NSNotification *)notification;
- (void)mkEnvObserverApplicationStatusBarFrameUserInfoKey:(NSNotification *)notification;
@end
(2)再次新建一个类ApplicationManager作为观察者,XMPPManager,Location作为被观察者并加入ApplicationManager的数组中,并且让他们实现(1)的协议。
(3)在 ApplicationManager初始化方法注册系统通知。
- (id)init
self = [super init];
if (self)
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appNotification:)
name:UIApplicationDidEnterBackgroundNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appNotification:)
name:UIApplicationWillEnterForegroundNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appNotification:)
name:UIApplicationDidFinishLaunchingNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appNotification:)
name:UIApplicationDidBecomeActiveNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appNotification:)
name:UIApplicationWillResignActiveNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appNotification:)
name:UIApplicationDidReceiveMemoryWarningNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appNotification:)
name:UIApplicationWillTerminateNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appNotification:)
name:UIApplicationSignificantTimeChangeNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appNotification:)
name:UIApplicationWillChangeStatusBarOrientationNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appNotification:)
name:UIApplicationDidChangeStatusBarOrientationNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appNotification:)
name:UIApplicationStatusBarOrientationUserInfoKey
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appNotification:)
name:UIApplicationWillChangeStatusBarFrameNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appNotification:)
name:UIApplicationDidChangeStatusBarFrameNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appNotification:)
name:UIApplicationStatusBarFrameUserInfoKey
object:nil];
return self;
(4)当系统自动post通知时,循环调用观察者实现的代理相应的方法。
- (void)appNotification:(NSNotification *)notification
NSString * name = [notification name];
SEL s;
if ([name isEqualToString:UIApplicationDidEnterBackgroundNotification])
s = @selector(mkEnvObserverApplicationDidEnterBackground:);
else if ([name isEqualToString:UIApplicationWillEnterForegroundNotification])
s = @selector(mkEnvObserverApplicationWillEnterForeground:);
else if ([name isEqualToString:UIApplicationDidFinishLaunchingNotification])
s = @selector(mkEnvObserverApplicationDidFinishLaunching:);
else if ([name isEqualToString:UIApplicationDidBecomeActiveNotification])
s = @selector(mkEnvObserverApplicationDidBecomeActive:);
else if ([name isEqualToString:UIApplicationWillResignActiveNotification])
s = @selector(mkEnvObserverApplicationWillResignActive:);
else if ([name isEqualToString:UIApplicationDidReceiveMemoryWarningNotification])
s = @selector(mkEnvObserverApplicationDidReceiveMemoryWarning:);
else if ([name isEqualToString:UIApplicationWillTerminateNotification])
s = @selector(mkEnvObserverApplicationWillTerminate:);
else if ([name isEqualToString:UIApplicationSignificantTimeChangeNotification])
s = @selector(mkEnvObserverApplicationSignificantTimeChange:);
else if ([name isEqualToString:UIApplicationWillChangeStatusBarOrientationNotification])
s = @selector(mkEnvObserverApplicationWillChangeStatusBarOrientation:);
else if ([name isEqualToString:UIApplicationDidChangeStatusBarOrientationNotification])
s = @selector(mkEnvObserverApplicationDidChangeStatusBarOrientation:);
else if ([name isEqualToString:UIApplicationStatusBarOrientationUserInfoKey])
s = @selector(mkEnvObserverApplicationStatusBarOrientationUserInfoKey:);
else if ([name isEqualToString:UIApplicationWillChangeStatusBarFrameNotification])
s = @selector(mkEnvObserverApplicationWillChangeStatusBarFrame:);
else if ([name isEqualToString:UIApplicationDidChangeStatusBarFrameNotification])
s = @selector(mkEnvObserverApplicationDidChangeStatusBarFrame:);
else if ([name isEqualToString:UIApplicationStatusBarFrameUserInfoKey])
s = @selector(mkEnvObserverApplicationStatusBarFrameUserInfoKey:);
else
return;
for (MKObserver * ob in _observersAry)
id<MKEnvObserverApplicationProtocol> observer = ob.observer;
if ([observer respondsToSelector:s])
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[observer performSelector:s withObject:notification];
#pragma clang diagnostic pop
以上是关于自定义通知的主要内容,如果未能解决你的问题,请参考以下文章