当前位置: 首页 > news >正文

达州达县网站建设我要自学网网站

达州达县网站建设,我要自学网网站,线上网课,怎么找推广渠道说到block#xff0c;相信大部分iOS开发者都会想到retain cycle或是__block修饰的变量。 但是本文将忽略这些老生常谈的讨论#xff0c;而是将重点放在美团iOS在实践中对block的应用#xff0c;希望能对同行有所助益。 本文假设读者对block有一定的了解。 从闭包说起 在Lisp… 说到block相信大部分iOS开发者都会想到retain cycle或是__block修饰的变量。 但是本文将忽略这些老生常谈的讨论而是将重点放在美团iOS在实践中对block的应用希望能对同行有所助益。 本文假设读者对block有一定的了解。 从闭包说起 在Lisp这样的语言中有一个概念叫做闭包closure1指的是一个函数以及它所处的词法作用域lexical scope2构成的整体。为了理解闭包我们首先来看看什么是词法作用域。 所谓词法作用域顾名思义是指一个符号引用的是其词法环境中的变量而无关程序在运行时的状态。这么说可能有点抽象让我来看一段Common Lisp3代码 (defvar printer (let ((x 42))(lambda () (format t ~a x))))这里我们定义了一个变量printer它的值是一个函数这个函数会打印词法作用域中的变量x其值为42。 现在我们来调用这个函数 CL-USER (funcall printer) 42可以看到我们调用了printer中存放的函数之后打印出来的数字是42跟我们的预期相符。 接下来再让我们看一个可能会出乎意料的结果 CL-USER (let ((x 1))(funcall printer)) 42我们在调用之前把x设置为了1但是打印的结果仍然是42。 为什么因为printer中存放的函数在被调用时所引用的变量位于其词法作用域中 即该函数被定义时所处的词法环境中所以程序在运行时设置的变量x对函数不起作用。 前面我们讲过所谓闭包就是函数及其词法作用域的合称具体到上例那么匿名函数和x就构成了一个闭包它会为函数保存一种状态有点类似于全局变量不过除了那个匿名函数其他函数无法访问到x。 说了这么多似乎跟block毫无关系事实上block为C带来了闭包。 Block Apple从OS X 10.6和iOS 4以后开始支持block让我们用C把上面的例子重写一下 #include stdio.hint main () {int x 42;void (^block)() ^() {printf(%d\n, x);};block();x 1;block();return 0; }编译运行后得到的输出同样是两个42。 到了这里相信读者对闭包已经有一个直观的认识了但是它有什么用有什么好处 设想如下场景我们要请求一个URL并以block的形式传入回调函数并在回调函数中用到刚才这个URL NSURL *someURL …; [SomeClass getURL:someURL finished:^(id responseObject) {// process responseObject with someURL }];这里网络请求是异步的所以当block中代码执行时getURL:finished:方法调用所在的栈很可能已经不存在了但是因为回调block和someURL构成了closure所以即使栈不存在block仍然可以引用到someURL。 可能你会说“我在block中增加一个NSURL类型的参数把someURL传回来不也可以实现同样的目的吗”不妨设想如果我们在block中要引用的对象有10个之多用参数列表传递明显不再现实用容器类或者专门定义一个类来传递虽然可以但是前者没有编译器为我们检查错误后者则相当繁琐。而利用闭包可以轻易达到灵活性和简洁性的平衡。事实上美团客户端就大量利用了闭包在UI层发出请求在回调中更新某些UI组件。 函数式编程4 在Lisp中函数是一等公民可以随时创建、作为参数传递、作为返回值返回Objective C在没有block之前没有类似的机制有了blockObjective C也就具备了函数式编程的能力block是对象有自己的ISA指针可以随时创建作为参数传递作为返回值返回。 先来看看block的经典用法 [UIView animateWithDuration:0.25 animations:^{self.view.alpha 1.0f;}];UIView的animateWithDuration:animations:方法的第二个参数是一个block它把跟动画相关的操作封装起来传递进去以实现动画效果。 现在让我们发掘一下类似的用法 [SAKBaseModel comboRequest:^() {[dealModel fetchDealByID:123456withFields:nilcompletion:^(MTDeal *deal, NSError *error) {...}];[orderModel fetchOrderByID:654321withDealFields:nilcompletion:^(MTOrder *order, NSError *error) {...}]; }];这里我们为SAKBaseModel设计了一个类似于UIView的接口叫comboRequest它会接受一个block作为参数在这个block中发出的请求都会作为combo请求的一部分。如果dealModel或者orderModel的任何一个请求不是出现在block中那么它就是一个普通的请求。这样做的好处是dealModel和orderModel的接口不需要关心自己是不是属于一个combo请求调用者则可以灵活地调整代码。 那么怎么实现这样的接口呢还是从UIView上获取灵感。我们知道UIView有个方法setAnimationsEnabled:实际上SAKBaseModel也可以有这么一个方法setComboRequestEnabled:而在comboRequest方法的实现中在调用传进来的block之前先setComboRequestEnabled:YES调用完后再恢复为原状态。相应的在实际的model接口中检查comboRequest是否为YES如果是则把自己作为一个combo请求的一部分否则正常发出请求即可。 Think Big Lisp最强大的特性之一是condition系统它可以分离异常的检测、异常的解决和异常解决方式的决策看一段示例代码 (define-condition network-timeout-error (error)((url :initarg :url :accessor url)))(defun try-again (condition)(let ((restart (find-restart ‘try-again)))(when restart (invoke-restart restart))))(defun deal-requester (deal-id)(handler-bind ((network-timeout-error #’try-again))(request-from-url (format nil “http://api.mobile.meituan.com/deal/~a” deal-id)(lambda (deal error)(if error(format t “error: ~a”, error)(process-deal)))))) (defun request-from-url (url finished)(let ((callback (lambda (response error)(if (network-timeout-error-p error)(error ‘network-timeout-error :url url)(funcall finished (parse-deal response) error)))))(restart-bind((try-again (lambda () (http-request url callback))))(http-request url callback))))可以看到condition系统对于代码的分层提供了良好的支持请求超时的错误在底层代码被检测到在发出请求前注册一个restart而在业务层去决定要不要调用restart。 一直以来C语言要实现优雅的异常处理就是一件不简单的事情而Objective-C虽然加入了try-catch支持但是苹果并不鼓励使用那么能否实现类似于condition系统这样的异常处理机制呢 答案是能。让我们来看看接口设计 typedef void (^RESTART)(id userInfo); typedef void (^HANDLER)(id condition);void restart_bind(void (^body)(), NSString *restartName, RESTART restart, ...) NS_REQUIRES_NIL_TERMINATION;void handler_bind(void (^body)(), Class class, HANDLER handler, ...) NS_REQUIRES_NIL_TERMINATION;void notify(id condition);RESTART find_restart(NSString *restartName);如下图所示handler_bind首先在栈中注册好handler而restart_bind则在handler有效的环境中注册restart当有异常发生时notify函数会在当前环境中寻找handler找到后控制会转移到上层的handler代码中这时handler可以用find_restart在栈中搜索restart找到之后可以调用从而实现异常的恢复做完这一切控制回到notify发生的点继续向下执行。 完整的代码敬请期待美团iOS的开源项目。 有了SAKCondition我们可以实现任意底层代码的逻辑穿透到上层代码比如网络层和UI层使得上层代码可以在不了解下层代码实现细节的情况下调用恢复机制。事实上美团的iPhone客户端就是利用SAKCondition实现了美团账户的安全解锁功能。 总结 block给Objective C带来了无穷的可能性。本文只讨论了美团iOS在实践中的一些用法更多想法还在等待挖掘。
http://www.zqtcl.cn/news/987208/

相关文章:

  • 电影网站模板html微信开发者代码管理
  • 小程序ui界面设计手机优化大师官网
  • 佳木斯市建设局网站网络游戏名
  • 建筑钢结构网站汉阳网站建设哪家便宜
  • 营销型网站建设评价临湘网站建设
  • 做网站的价格参考巴中建网站的公司
  • 张家口建设网站网络技术工程师
  • 大型网站后台登录地址一般是如何设置的哪里网站用vue.js做的
  • 网页设计规范图标设计百度seo优化多少钱
  • 网站打开速度概念建筑网站知乎
  • 网站的flash怎么做的杭州市城乡建设网官网
  • 宿迁网站建设排名wordpress多站点可视化
  • 苏州好的做网站的公司哪家好前端如何做响应式网站
  • 广州网站建设招标推广方式有哪些渠道
  • 郑州做网站狼牙东莞建设造价信息网站
  • 网站制作代理加盟国内seo服务商
  • 如何在建设银行网站预约纪念币网络销售好不好做
  • 利用淘宝视频服务做视频网站聊城做网站价格
  • 做美容行业的网站哪个好广西互联网企业
  • 做网站平台的营业执照江镇做包子网站
  • 网站建设 摄影服务wordpress破解模板
  • 网站规划中的三种常用类型宁波海曙区建设局网站
  • dede做网站湖北网址大全
  • 如何注册网站的名字html表单制作
  • 中国建设工程协会标准网站什么网站做推广比较好
  • 长沙专业网站建设怎么做关于网站建设的投标书
  • 石家庄公司网站如何制作wordpress 大图 主题
  • 网站建设和管理情况如何传图片做网站
  • 网站建设流量什么意思杭州企业网站设计模板
  • 义乌网站制作是什么交互式网站