本文共 2248 字,大约阅读时间需要 7 分钟。
NSNotification与NSNotificationCenter是离不开的。NSNotificationCenter就像是一个广播站,它会播放各种广播(即NSNotification),你可以选择打开(即添加observer)某一个或者多个广播来收听,而广播不总是在播放的,每当广播站发送(post NSNotification)一次你就收到一次,你可以在收到广播之后做出相应的响应(即NSNotification在observer中 的 selector)。当然,广播的听众也可以不只是一个。
比如说,UIApplicationWillEnterForegroundNotification。每当app进入进入background,将会发送一个名字叫做UIApplicationWillEnterForegroundNotification的NSNotification,如果你添加为这个NSNotification的observer,那么就会接收到这个NSNotification,你可以在接收到之后做出响应,比如说保存未保存的数据等。
下面来实现一个简单的NSNotification。
首先需要定义一种NSNotification。
我们把定义NSNotification的类叫做FileDownloadManager(假定它内部实现了下载功能)。
首先,要给NSNotification起一个名字。在FileDownloadManager.h中定义
extern NSString *const FILE_DIDDOWNLOAD_NOTIFICATION;在FileDownloadManager.m中给它赋值。
NSString *const FILE_DIDDOWNLOAD_NOTIFICATION = @"FILE_DIDDOWNLOAD_NOTIFICATION";
FILE_DIDDOWNLOAD_NOTIFICATION就是这个NSNotification的名字。
每当FileDownloadManager完成一次下载将发总一次NSNotification,即定义及发送NSNotification。
NSNotification *notification = [NSNotification notificationWithName: FILE_DIDDOWNLOAD_NOTIFICATION object:nil userInfo:[NSDictionary dictionaryWithObjectsAndKeys:fileName, @"fileName", nil]];[[NSNotificationCenter defaultCenter] postNotification:notification];
这样就发送了一个NSNotification,其中userInfo是一个NSDictionary,其中包含了需要发送的信息,这里就包含了下载的文件名。
然后就是接收,比如我们要在一个叫做ViewController的类中就收。那么需要加入以下代码。
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(fileDidDownload:) name: FILE_DIDDOWNLOAD_NOTIFICATION object:nil];
这样,每当FILE_DIDDOWNLOAD_NOTIFICATION被发送时,ViewController就会接收到。并调用ViewController中的fileDidDownload:方法。
fileDidDownload方法可以这么写:
- (void)fileDidDownload:(NSNotification *)notification{ NSString *fileName = [notification.userInfo valueForKey:@"fileName"]; ……}
这样就取出了传过来的值。
每当添加observer,我们就要在适当的时候remove这个observer。比如说你在viewWillAppear中添加的observer那么每次viewWillAppear执行都会添加一次observer,那么每当发送一个FILE_DIDDOWNLOAD_NOTIFICATION,这个ViewController就会调用多次fileDidDownload:。remove observer方法如下。
[[NSNotificationCenter defaultCenter] removeObserver:self name: FILE_DIDDOWNLOAD_NOTIFICATION object:nil];
NSNotification与线程。
这是需要注意的一点,还是拿上面的例子来说。比如我在一个background线程中postNotification,那么如果你不指定线程,fileDidDownload:方法中的代码也将在postNotification的同一个线程中执行。所以比如我们要在fileDidDownload中执行一些view的更新等操作,就必须保证在主线程中执行。可以通过dispatch queue等方法来实现。
转载地址:http://bmvpi.baihongyu.com/