Block(函数式编程思想)
- Block是一个数据类型,有自己的ISA指针,可以保存代码块,多用于参数的传递,只有调用Block的时候才会执行Block中的代理块
- 定义一个block的时候需要用copy,代码块是在栈区分配,一旦离开作用域就会被释放,所以要用copy
- __Block关键字理解
- 正常情况下,在Block{ }中不能对外面的变量进行更改(报错)
- 给想要更改的变量加上__Block关键字即可
- Block理解
- 自身view功能不能实现时,自定义一个block请求控制器去实现
- block传的参数是给控制器用来实现方法
- 解决Block循环引用问题
- 当在大括号中出现self或者下划线的属性,可能造成死循环
- __weak typeof (self) weakSelf =self typeof( )会自动识别括号中的对象类型
- 与delegate区别
- delegate回调更多的时面向过程,block则面向结果
- block在回调上使用起来更加方便和简单,其可以传递多个参数,而且还有返回值
- 回传断言:在调用方调用执行方的block的时候,此处可以在主调方用到断言( NSAssert(self.mmBlock!=nil, @"block回调一定要实现哦!"); )
- 当在回调是有多个代理方法的时候,推荐使用代理,因为此时只需要定义一次代理和协议,而block需要多次定义
- 在实际的案例中各有所长,本人比较倾向于使用block,两者选择的时候,如果同时需要声明多个协议方法,那么选择代理,以上是我在平时工作中积累的一点小经验,希望能帮到你们,,,,对于初学者建议使用代理,因为代理的阅读性高
代理/通知
- 代理存在的意义,面向过程思想,将业务逻辑模块化
- 代理是一对一,在代理中,只有声明并实现了代理协议的对象才能调用
- 一个协议遵守了另外一个协议中,那么它就有了另一份协议中的方法的声明
- 一个协议在指定的代理中实现的时候必须要在定义协议的类中做出判断,此处可以用到断言( NSAssert(self.mmBlock!=nil,@"block回调一定要实现哦!"); )
- UITableView中的优化后的代理图示如下:
- 代理只有一个用途:用来声明一大堆的方法,不能声明成员变量,不能写实现
- 通知是多对多
- 监听器可以监听多个不同条件的通知,也可以监听多个人发布的通知,不需要知道谁发通知谁接收通知
- 监听范围是整个应用
- 通知的主要用是监听,不同于block和代理,通知的可接受范围更加广泛,功能模块之间的传值通信是多对象对多对象之间
- 通知的三部曲:通知的发布,通知的监听,通知的销毁 在监听通知回调的环节,可以同过打印通知对象的userInfo来打印出用户发布时的详细信息
- 下面给大家来一点代码swift版的通知实例使用步骤吧
1.监听键盘frame发生改变时的通知
//注册键盘frame变化的通知
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ALComposeControler.beginEditing(_:)), name: UIKeyboardWillChangeFrameNotification, object:nil)
2.通过监听键盘的改变设置view上自定义toolbar的y方向的约束的改变
@objc privatefunc beginEditing(notification:NSNotification){
//获取键盘的frame
let keyFrame = notification.userInfo!["UIKeyboardFrameEndUserInfoKey"]!.CGRectValue
//动画时长
let timeDuration:NSTimeInterval = notification.userInfo!["UIKeyboardAnimationDurationUserInfoKey"]!.doubleValue
let y = -(UIScreen.mainScreen().bounds.height-keyFrame.origin.y)
self.toolbar.snp_updateConstraints(closure: { (make)in
make.bottom.equalTo(self.view).offset(y)
})
//动画改变toolBar的y方向的约束
UIView.animateWithDuration(timeDuration) {
self.toolbar.layoutIfNeeded()
}
}
3.最后一定要记得通知的销毁(相当于OC中的dealloc中销毁)
//移除通知
deinit{
NSNotificationCenter.defaultCenter().removeObserver(self)
}
OC中的block/swift闭包
1.两者的使用方式完全相同,分为三步:
1>定义block/闭包
// 闭包使用流程1.定义闭包属性,传递
var
2>调用block/闭包
// 闭包使用流程2.调用闭包
?()
3>调用别人设置好的闭包
// 闭包调用流程3.调用别人设置的闭包
mainTabBar.composeClosure = { () -> Void in
// 闭包调用流程4.执行闭包里面的代码
if !HMUserAccountViewModel.sharedInstance.userLogin {
SVProgressHUD.showErrorWithStatus("请先登录...")
return
}
// 创建转撰写微博界面
let composeVC = HMComposeViewController()
let nav = UINavigationController(rootViewController: composeVC)
self.presentViewController(nav, animated: true, completion: nil)
}