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等等。