关闭

Block与代理的联系与区别

标签: block代理
250人阅读 评论(0) 收藏 举报
分类:

Block与代理的联系与区别

Block是引进的对C语言的扩展,用来实现匿名函数的特性。
Block是Apple Inc.为C、C++以及Objective-C添加的特性,使得这些语言可以用类lambda表达式的语法来创建闭包。
闭包就是能够读取其它函数内部变量的函数。就是在一段请求连续代码中可以看到调用参数(如发送请求)和响应结果。所以采用Block技术能够抽象出很多共用函数,提高了代码的可读性,可维护性,封装性。

不像代理声明了一个代理函数,在调用的类内部还要实现该函数,让人莫名惊诧,若一个页面能发送多个请求,并且用多点触控同时触发发送多个请求,那个这个页面的代理函数很难区分是那个请求的结果,胡乱解析消息很容易崩溃。有人说我发送一个请求就是个菊花,消息不返回,不让发其他请求。告诉你这个行不通,原因是弹出菊花是起一个线程,调用发起线程很快会返回成功,但是你发起的线程被加入主线程并且实际运行起来是需要时间的,大约需要130毫秒,并且那个提示菊花提示框也是刷新UI线程才出来的。所以当你两个手指同时点击两个发送请求或切换页面的按钮时,在当点击第一个按钮并发起菊花消息,但是在菊花出现之前点击了另一个按钮时,那么你就连续发送了两个请求了。那么你用代理实现时就很难分出那个消息,只有你的响应消息中带有消息类型可能会分出来,若服务器做的不够强大,当出现异常时,找不发送请求,给你来个通用错误响应消息,你只有傻眼了。这样多个消息在一个函数里解析也不利于封装。
* 综上所述:Block就是把你发送的请求和响应放在一块,配成一对,所以又叫代码块嘛。

  1. Block的优点:是能把发起的部分和响应的部分放在一起,可以很容易的理解和处理。
  2. 缺点是若你的响应部分处理不当,若多次返回,那么你的代码会乱套;若你返回时错误返回了其它的代码块就会出现跑到其它流程里面去;最严重的是若代码永远不返回,那么你的程序又是根据返回结果跳转页面的,那么你永远停留在原页面,并且会造成内存不能释放。

举个实际的例子,我发送下线请求,由于代码写的有问题,导致在长连接线程里返回的上线成功的block,结果导致程序走入上线流程里了(上线block处理部分)。

代理也有其优点和适用场景:代理在自定义控件方面具有其绝对的优势。如:你想定义一个显示无网络信息的标签和一个按钮,当你点击按钮时进行操作(切换检查的网络地址,IOS自带的网络检查是连接到苹果服务器域名。点击按钮时你可以检查你服务器的域名)域名来最终显示或隐藏这个图层,那么这个图层可以抽象成一个控件,这个控件的响应函数就用代理函数来实现。以前我的文章介绍的小气泡的控件实现方法也是用代理实现了。

  • 适合代理实现的方法有一个显著的特点,只需要处理响应(如:按钮响应事件),没有或不考虑发起者。代理方法在自定义控件上大展宏图。
  • 适合BLOCK的显著特点,有明确的发起方和响应方,两者能配对需要紧密联系。如:网络请求。

虽然block使用起来非常灵活,但代理也有其方便之处。

  • 举个例子说明:block要传递该函数,首先函数中的对方必须是在函数体中声明或者是引用了外部的对象。这就有个问题,就是在写函数声明的时候,里面的对象都存在了,或者说了先有了对象,后面启动block的时候,才进行的回调。

  • 代理对于解决这种不可预知的对象是很有帮助的,实际上我不需要管你是否存在,我就可以调用让你执行这个协议方法。这是因为代理的启动可以加判断,如:if(self.delegate &&self.delegate responseto:),加了这个判断之后,你对象有没有我也不关心,反正对象有,我就启动,没有就不启动。就是这么简单。这对于解决我不确定对象存在的情况下,是很有用处的。
    如XMPP协议中,登录进去之后,XMPP首先就执行了didreceivePresent这个方法。执行过后,本来要更新在线联系人列表,这个列表可以更新,但是是否要刷新UI,就很难判断。因为UI的启动时间很难把握,可能在didreceivepresent之前或者之后都有可能。这个时候,可以通过代理,启动刷新相关UI,如果那个controller存在,就刷新,不存在,就不刷新,UI启动后会自己更新最新的在线联系人数据。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:43986次
    • 积分:970
    • 等级:
    • 排名:千里之外
    • 原创:56篇
    • 转载:8篇
    • 译文:0篇
    • 评论:4条