通知传值
首先我们来看看通知传值,通知可实现任意界面之间的数据传递,但必须满足一个条件,就是保证在发送通知的时候监听者已经存在(先要注册通知)。而通知的注册主要通过NSNotificationCenter通知中心实现,其为一个系统单例,系统提供了defaultCenter()方法获取通知实例对象。
通知使用步骤:注册通知 -> 发送通知 -> 移除通知
通知实现的原理,我们可以这样去理解,学生监听下课铃声。我们把学生看做监听者(或者叫观察者),监听铃声,铃声一响就放学。当铃声响起时,我们看做发出一个通知(信号),学生在监听到铃声之后就会做出相应的操作,比如放学之后做什么……
接下来我们看看通知传值的具体实现方式。这里我们模拟从详情界面传值到主界面,为了统一,下文都用ViewController表示主界面,DetailViewController表示详情界面。首先我们需要在主界面注册通知,因为,程序运行肯定是先到主界面中,所以,当在详情界面发送通知的时候,通知监听者肯定是存在的。注册通知的方法常用的有以下两种:
// 1、publicfunc addObserver(observer: AnyObject, selector aSelector: Selector, name aName:String?, object anObject: AnyObject?)// 2、publicfunc addObserverForName(name:String?, object obj: AnyObject?,queue: NSOperationQueue?, usingBlock block: (NSNotification)->Void)->NSObjectProtocol
第1种,我们需要通过Selector参数设置接收到通知时触发的方法。而第2种,我们无需关联触发方法,在方法尾部跟着一个闭包,当接收到通知的时候该闭包会自动调用,我们可直接在闭包内处理相应的逻辑即可。第2种方法还有一个参数queue,该参数主要设置通知触发方法执行的队列,其为NSOperationQueue类型的对象,这里我们一般在主队列执行,配置参数方法为NSOperationQueue.mainQueue()。我们可以直观的看到,在两种方法中都有一个name参数,该参数我们可以理解为通知的代号,通过这个代号我们可以避免多个通知串联,这个参数我们可以赋值任意字符串。此处以第2种为例。
//1、register notificationNSNotificationCenter.defaultCenter().addObserverForName("notification_name", object: nil, queue: NSOperationQueue.mainQueue()) { (info: NSNotification) -> Voidin// 处理接收到通知之后执行的逻辑...}
通知注册好之后,下一步我们就可以在详情界面发送通知了,我们在处理界面跳转(返回)的方法中处理这一逻辑。发送通知主要用到以下方法:
// 发送通知publicfuncpostNotificationName(aName: String,objectanObject: AnyObject?, userInfo aUserInfo: [NSObject : AnyObject]?)
这里需要注意,发送通知的aName参数,必须和注册通知时的name参数一致,否则在主界面将无法接收到通知。我们可通过aUserInfo参数将需要传递的数据传递到主界面中,该参数为一个[NSObject : AnyObject]?(字典)类型的数据。实现示例如下:
func respondsToBtn(sender:UIButton) {// 2、post notification and send valueNSNotificationCenter.defaultCenter().postNotificationName("notification_name", object:nil, userInfo: ["text":self.textField.text!])self.dismissViewControllerAnimated(true, completion:nil)}
当用户点击返回按钮时,发送通知,主界面接收到对应通知之后将会回调闭包,我们可在闭包中打印传递过来的数据,如下所示:
NSNotificationCenter.defaultCenter().addObserverForName("notification_name", object: nil, queue: NSOperationQueue.mainQueue()){(info)->Voidinprint((info.userInfo!["text"])!)
}
到了这一步,我们已经基本实现通知传值了,我们还需要最后一步,移除通知,通知的移除我们可在界面释放的方法(析构方法)中去执行,如下所示:
deinit {
// 3、removenotificationNSNotificationCenter.defaultCenter().removeObserver(self)
}