通告机制Notification

Obj-c的基本通讯原则是对象间的消息传递,这种情况多出现在两个对象之间。但是如果多个对象共同关注一个对象状态的时候呢,当然可以让发生事件的对象向所有关注他的对象发送消息,但是这并不高效。所以有了通告中心,让发生事件的对象向通告中心发布通告,然后由通告中心向注册成为观察器的对象发布通告。

若将某个对象注册为观察器,需要制定通告名称、发布通告的对象和接收相应通告的方法的方法名。比如我将self注册为观察器,通告名称是getMarried,发送对象可以是任意对象,则当任何一个对象发布getMarried通告时,self对象就会收到blessing:消息

NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self selector:@selector(blessing:) name:@"getMarried" object:nil];


这个通知中心的工作流程大概如下图


需要注意的是,如果程序已经释放了某个注册成为观察器的对象,却没有将其移出通告中心,那么发送"getMarried"事件时,就会向原有的引用发送消息而导致程序崩溃。所以在释放时需要将其移出通告中心。

- (void)dealloc
{
   [[NSNotificationCenter defaultCenter] removeObserver:self];
   [super dealloc];
}


UIDevice通告


UIKit中的UIDevice对象可以不间断的发送通告

    UIDevice *device = [UIDevice currentDevice];
    device.batteryMonitoringEnabled = YES;
    
    NSNotificationCenter *nc = [[NSNotificationCenter alloc] init];
    [nc addObserver:self selector:@selector(batteryLevelChanged:) name:UIDeviceBatteryLevelDidChangeNotification object:device];


UIDeviceBatteryLevelDidChangeNotification是一个常量,表示电量发生改变时发布通告,处理方法是batteryLevelChanged:

- (void)batteryLevelChanged:(NSNotification *)note
{
    UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"电量改变"
                                                 message:@"电量发生了改变"
                                                delegate:nil
         cancelButtonTitle:@"知道了" otherButtonTitles:nil];
    [av show];
}


UIDevice对象发布通告的常量除了电量改变以外还有

UIDeviceOrientationDidChangeNotification         // 传感方向发生变化通告

UIDeviceBatteryStateDidChangeNotification       // 电池状态发生变化通告

UIDeviceProximityStateDidChangeNotification   // 设备靠近面部时通告


Cocoa Touch中的其他很多类也会发布通告,如UIApplication,MPMoviePlayerController,NSFileHandle等等。




原文地址:https://www.cnblogs.com/jiangu66/p/3165576.html