通知,block 代理 通知 区别,block的区别和用法

文/yeahming(简书作者)
原文链接:/p/
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
首先说一下在OC语言中消息通知的常用几种方式。
第一就是代理,这也是很常用的方式,特点是一对一的形式,而且逻辑结构非常清晰。实现起来较为简单:写协议 ,设置代理这个属性, &最好在你想通知代理做事情的方法中调用即可。当然这里面有一些细节,包括 ①协议定义时,请用关键字@required,和@optional来明确代理是否必须实现某些方法 ②代理的类型需用id类型,并写明要遵守的协议 ③就是在调用代理方法的时候需要判断代理是否实现该方法。
第二就是通知,通知的优点很明显,他是一对多的形式,而且可以在任意对象之间传递,不需要二者有联系,当然他的实现和代理相比较稍微绕一点,注册,发通知,收通知。这里面的注意点就是 ①对于系统没有定义的事件监听时需要自己发通知,这是你就需要定义一个key,字符串类型,这也是通知的一个弊端,你需要拷贝到收通知的对象,避免写错一个字母而无法收通知的尴尬 ②就是注册的通知中心需要手动移除,不然除了性能的问题还会有其他的问题出现,比如说一个控制器消失了之后还有因为某些事件而发出通知,造成不想要的结果。
第三就是block了,这是苹果后来才加入的,也是目前开发比较常用的一种方式,功能比较强大,但是在理解和使用上可能需要一段时间摸索和熟悉。他的最大特点就是回调,而且回调时可以传入参数,最重要的是,无论在哪调用,block的执行都会回到block创建的地方执行,而非调用的地方。而block本身可以封装一段代码,一段代码你懂的,很多人在初学时会被搞晕,甚至在block的声明上就纠结,其实很正常,多用就好。
此处还是简单说一下语法的东西 ①声明分为3部分 返回值类型 + 变量名 + 参数 比如 成员变量的声明 void (^myblock)(int a) &
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:4775次
排名:千里之外
原创:15篇
(1)(1)(10)(9)(1): 一对一& 一对多& 传值
四个步骤:&
&1.发送通知
2.创建监听者
3.接收通知
4.移除监听者
1- 很多控制器都需要知道一个事件,应该用通知;
2 - 相隔多层的两个控制器之间跳转
& 1, 一旦接收消息的对象多了,就难以控制了,可能有你不希望的对象接受了消息并做了处理
&2,创建了观察者,在dealloc里面一定要移除;
—————————————————————————————————————————————————————————————
“一对一”,对同一个协议,一个对象只能设置一个代理delegate
1.声明一个协议,定义代理方法
2. 遵循协议
3.设置一个代理对象
4.调用代理方法
5.给代理赋值
6.实现代理方法
1,单例对象不能用代理;
2,代理执行协议方法时要使用 respondsToSelector检查其代理是否符合协议(检查对象能否响应指定的消息),以避免代理在回调时因为没有实现方法而造成程序崩溃
&使用场景:
公共接口,方法较多也选择用delegate进行解耦&
iOS最常用tableViewDelegate,textViewDelegate&
&iOS有很多例子比如常用的网络库AFNetwork,ASIHTTP库,UIAlertView类。
—————————————————————————————————————————————————————————————
什么是Block:
Block是iOS4.0+ 和Mac OS X 10.6+ 引进的对C语言的扩展,用来实现匿名函数的特性。
Blocks语法块代码以闭包得形式将各种内容进行传递,可以是代码,可以是数组无所不能。
闭包就是能够读取其它函数内部变量的函数。就是在一段请求连续代码中可以看到调用参数(如发送请求)和响应结果。所以采用Block技术能够抽象出很多共用函数,提高了代码的可读性,可维护性,封装性。
使用场景:
二:数据请求回调
三:枚举回调
四:多线程gcd
&异步和简单的回调用block更好&
BLOCK最典型的是大所周知的AFNETWORK第三方库。
block需要注意防止循环引用:
&&& ARC下这样防止:
__weak typeof(self) weakSelf =
& [yourBlock:^(NSArray *repeatedArray, NSArray *incompleteArray) {
&&&&&& [weakSelf doSomething];
&&&& 非ARC
__block typeof(self) weakSelf =
& [yourBlock:^(NSArray *repeatedArray, NSArray *incompleteArray) {
&&&&&& [weakSelf doSomething];
———————————————————————————————————————————————————————————
delegate 和 block对比
&&& 效率:Delegate比NSNOtification高;?
&1,&& Delegate和Block一般都是一对一的通信;?
&2,&& Delegate需要定义协议方法,代理对象实现协议方法,并且需要建立代理关系才可以实现通信;?
&&&&& Block:Block更加简洁,不需要定义繁琐的协议方法,但通信事件比较多的话,建议使用Delegate;?
3,& delegate运行成本低。block成本很高的。
block出栈需要将使用的数据从栈内存拷贝到堆内存,当然对象的话就是加计数,使用完或者block置nil后才消除;delegate只是保存了一个对象指针,直接回调,没有额外消耗。相对C的函数指针,只多做了一个查表动作 .
4,代理更注重过程信息的传输:比如发起一个网络请求,可能想要知道此时请求是否已经开始、是否收到了数据、数据是否已经接受完成、数据接收失败
&&& block注重结果的传输:比如对于一个事件,只想知道成功或者失败,并不需要知道进行了多少或者额外的一些信息
5 Blocks 更清晰。比如 一个 viewController 中有多个弹窗事件,Delegate 就得对每个事件进行判断识别来源。而 Blocks 就可以在创建事件的时候区分开来了。这也是为什么现在苹果 API 中越来越多地使用 Blocks 而不是 Delegate。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:7487次
排名:千里之外
原创:89篇
(13)(2)(17)(27)(25)(5)通知, 代理, block的数据传递 - 简书
通知, 代理, block的数据传递
通常我们实现的数据传递方式有:
1.1 通知 使用方法
添加监听通知
NSNotificationCenter.defaultCenter().addObserver(&#T##observer: AnyObject##AnyObject#&, selector: &#T##Selector#&, name: &#T##String?#&, object: &#T##AnyObject?#&)
添加发送通知
NSNotificationCenter.defaultCenter().postNotificationName(&#T##aName: String##String#&, object: &#T##AnyObject?#&)
NSNotificationCenter.defaultCenter().removeObserver(&#T##observer: AnyObject##AnyObject#&)
1.2 通知 使用场景
1. 当我们的view嵌套很深的时候, 这样我们无论使用代理还是block都将非常的麻烦.
2. 两个控制器之间没有什么必然的联系
1.3通知 使用缺点
1. 不利于我们维护我们的代码(添加通知和发送通知没有必然联系, 不像代理和block那样数据间有必然的联系)
2. 效率较低
3. 需要设置移除通知的方法(我经常忘记)
2.1 使用方法
记住使用代理就是 6个步骤就可以了!
1. 声明协议
2. 设置代理属性
3. 通知代理
4. 遵守协议
5. 设置成为代理
6. 实现代理
还是swift代码 代理的实现
// 1. 定义协议
@objc protocol ZXZPictureSelectorCellDelegate: NSObjectProtocol {
//定义协议方法
optional func userWillAddPicture()
optional func userWillDeletePicture(cell: HMPictureSelectorCell)
// 2. 代理对象的属性
要使用 weak 表示弱引用
weak var selectorDelegate: ZXZPictureSelectorCellDelegate?
selectorDelegate?.userWillAddPicture?()
// 4. 遵守协议
extension HMPictureSelectorController: HMPictureSelectorCellDelegate{
设置成为代理
cell.selectorDelegate = self
// 6. 实现代理
func userWillAddPicture() { /*内容就不贴了*/ }
func userWillDeletePicture(cell: ZXZPictureSelectorCell) {/*内容就不贴了*/ }
2.2 使用场景
1. 两者相对之间有一定的关联
2. 代理最常用的是反向传值!!!通知某个属性发生改变,让代理去实现!还有就是解耦!!!
2.3 使用缺点
1. 相对于block稍微麻烦一点(吹毛求疵了)
2. 当两者没有必然的联系 无法实现数据传递
3.1 使用方法
针对block的使用不想说太细 直接上代码, 改天我会总结block的用法
有需要的可以关注一下,
因为最近正在学习swift 我就贴上我swift单例封装的AFNetworking吧
class AFNetworkingTools: AFHTTPSessionManager {
//MARK: 声明一个单例对象
static let shareTools:AFNetworkingTools = {
let tools = AFNetworkingTools(baseURL: nil)
tools.responseSerializer.acceptableContentTypes?.insert("text/plain")
return tools
// MARK: - 封装POST和Get请求
func request(methods:HTTPMethods, urlString:String, parameters: [String:AnyObject]?, finash:((success: AnyObject?, error:NSError?) -& ()) ){
if methods == .GET {
GET(urlString, parameters: parameters, progress: nil, success: { (task, result) in
finash(success: result, error: nil)
}, failure: { (task, error) in
finash(success: nil, error: error)
POST(urlString, parameters: parameters, progress: nil, success: { (task, result) in
finash(success: result, error: nil)
}, failure: { (task, error) in
finash(success: nil, error: error)
我们对我们单例中疯装的block代码块进行调用
AFNetworkingTools.shareTools.request(HTTPMethods.GET, urlString: urlString, parameters: parama) { (success, error) in
if error != nil{
print("我们获取个人数据失败")
print("成功获取数据: ", success)
3.2 使用场景
两者有必然的关联的情况下 我们就可以实现block的回调实现数据传递
在我们的工作中要多使用block, block的使用有利于我们的维护代码.
而且使用也是最方便的(但是注意block引用循环的问题!!)
反向传值!!!通知某个属性发生改变,让代理去实现!还有就是解耦!!!
3.3 使用缺点
如果没有关联 数据将无法实现数据传递
以上是我个人理解 可能存在很多问题 还望大家多多指教! 如果有任何疑问还望大家留言,大家互相探讨
还望大家多多鼓励!!多多批评&&国之画&&&& &&
版权所有 京ICP备号-2
迷上了代码!KVO: 监听对象属性的变化
1?同步的,所有的监听方法执行会在属性变化的线程上执行,目的是为了保证顺序执行(属性改变后只有先执行完响应的代码才能执行改变属性的下一条语句),因为同步,所以不能线程间通信
2?如果多个线程同时修改一个属性,有可能会出现资源抢夺的问题(加上互斥锁《线程同步》)
// 互斥锁的参数必须是一个对象,任意一个对象都可以,但是不能是线程执行方法中定义的对象,一般用self即可
// // 每次进来之后都会创建一个objLock,默认是打开的,所以加跟没加都是一样的,都是打开的,都能进去
// NSObject *objLock = [[NSObject alloc]init];
// & & & @synchronized(objLock){
& & & & // 每一个对象(NSObject)内部都有一个锁(变量),当有线程要进入synchronized到代码块中会先检查对象的锁是打开还是关闭状态,默认锁是打开状态(1),如果是线程执行到代码块内部会先上锁(0)。如果锁被关闭,再有线程要执行代码块就先等待,直到锁打开才可以进去
& & & & // 这样就可以了 因为是同一把锁
& & & & @synchronized(self.objLock){
//& & & & @synchronized(self){
& & & & & & if (self.tickets & 0) {
& & & & & & & & self.tickets -- ;
& & & & & & & & NSLog(@"%d--%@",self.tickets,[NSThread currentThread]);
& & & & & & & &
& & & & & & }
3?如果监听的属性非常多,KVO的观察方法将非常难写
4?不用时要记得销毁,且先添加后销毁否则崩溃
?主要用于MVC中视图与模型的同步,当model对象改变时,视图应该随之改变
6?OC用run time机制来实现KVO 当我们第一次观察某个对象的属性时,run time会创建一个新的继承自这个对象的类的子类,在这个子类中,它会重写所有被观察的属性的setter方法,然后将对象的isa指针指向新创建的子类
1?可以是用户发出,也可以是系统发出,但是统一由兄台那个处理
2?defaultCenter 消息中心只有一个,通过类方法获取它的单例
3?同步的,在发送通知所在的线程执行
4?一定要记着销毁(dealloc)
代理:把某个对象要做的事委托给别的对象去做,那么别的对象就是这个对象的代理,代替它来打理要做的事
2?控制器之间传值
block:提前准备好的一段代码,在需要的时候调用
1?解决循环引用,一半是在block代码中使用了self & MRC:_block & ARC:_weak
2?block存储位置:
①代码区 没有访问block的外部变量
②栈区 访问外部变量& 其实block本质上是一个结构体,结构体存储在栈上
③堆区 实际上放在栈区,ARC情况下自动copy到堆区,MRC情况下存放在栈区,所以函数执行完就会释放,想在外边调用需要copy,这样就copy到堆区
strong,assign属性会出现野指针错误(程序崩溃),释放之后栈地址不会变
1?方法多时用代理
2?block和代理直接调用方法,效率高一点 通知基于KVO
3?如果想要双向交互就用代理、block,不能用通知
阅读(...) 评论()}

我要回帖

更多关于 block 代理 通知 区别 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信