(1)delegate
1解决对象对象间通信问题的关键:判断谁是代理对象,谁是被代理对象。
谁产生事件,就是被代理对象。被代理对象有一个delegate属性,并且在这个类里面定义一个protocol及其方法并且调用`,注意只是定义和调用,具体实现在下面的类里面。 定义的时候要注意用assign,如果用strong会出现内存泄漏:VC—>view—>tableView—>delegate(self即VC)
谁响应事件,就是代理对象。代理对象需要遵守协议,并且实现协议里面规定的方法
(2)block
解决对象对象间通信问题的关键:判断谁回调block,谁传递block (类似于delegate)
谁产生事件,谁就回调block。这个需要回调block的类需要定义block并且有一个block属性(定义block属性时需要用copy)。
谁响应事件,谁就传递block。接受到事件传递block时,block里面的具体操作在这里定义,但在传递时不会执行,执行是在上面回调block时block执行
(3)定义block属性需要用copy的原因
Block存储在栈区,栈区的特性是当一个方法运行完成之后里面的内存就会释放掉,如果block被释放,那么后面回调就会遇到问题,所以要把block复制到堆区来存储。所以用copy把整个block内容拷贝过来并且在堆区新建一块空间来存储block
(4)__block关键字的使用
首先,如果要在block内部修改局部变量,需要用__block修饰。当然被此关键字修饰的指针仍然是强指针,为了避免循环引用,修改前需要用__weak重新定义一个弱指针。例如
__weak typeof(self) weakSelf = self;
[yourBlock:^(NSArray *repeatedArray, NSArray *incompleteArray) {
[weakSelf doSomething];
}];
(5)几种通信方式的对比
通知:“一对多”,在APP中,很多控制器都需要知道一个事件,应该用通知;
delegate:
1.“一对一”,对同一个协议,一个对象只能设置一个代理delegate,所以单例对象就不能用代理;
2.代理更注重过程信息的传输:比如发起一个网络请求,可能想要知道此时请求是否已经开始、是否收到了数据、数据是否已经接受完成、数据接收失败
block:
1.写法更简练,不需要写protocol、函数等等
2.block注重结果的传输:比如对于一个事件,只想知道成功或者失败,并不需要知道进行了多少或者额外的一些信息
3.block需要注意防止循环引用: