初识Block的时候,总觉得其很可怕,因为看不懂其运行原理,所以用起来总是觉得不安全。关于Block的语法,等我把手里的资料全部看完,整理好再发出来。这次先看看用Block怎么实现回调。

新博客:wossoneri.com

关于Objective-C的回调,最常见的应该是用delegate代理实现。不过代理的实现比起Block要更基础,就不介绍了,下面总结一下Block回调的实现。

就拿我昨天才写的博客为例:[iOS] 输入框高度随输入内容变化

在昨天的例子中,我的组件封装控件后,是通过代理实现返回行数的变化的。这次改用Block来实现。

  1. 定义一个Block类型,用来代替原来的@Protocol
typedef void(^getTextViewRows)(NSInteger lines);
  1. interface中声明参数为Block的实例方法
- (void)textViewRowsChangeTo:(getTextViewRows)block;
  1. 实现textViewRowsChangeTo:的方法
- (void)textViewRowsChangeTo:(getTextViewRows)block {
block(lines);
}

唉,等等,我应该返回的行数是在textViewDidChange:运行时获得后才返回的啊,这样写还回调个什么鬼。。

所以我们需要声明一个Block变量,保存从外部传进来的Block的地址,然后当我们获取到改变的行数后,再从这个地址把正确的内容返回。

在第2步添加声明Block变量

@property (nonatomic, strong) getTextViewRows b_getRowsBlock;
- (void)textViewRowsChangeTo:(getTextViewRows)block;

修改第3步

- (void)textViewRowsChangeTo:(getTextViewRows)block {
_b_getRowsBlock = block;
}

然后在需要返回行数的时候,把行数作为参数传给Block

- (void)textViewDidChange:(UITextView *)textView {

    NSInteger numLines = textView.contentSize.height / textView.font.lineHeight;
if (numLines != rows) {
rows = numLines;
//发生换行
_b_getRowsBlock(rows);
} ......
}

最后,在外部调用前面的实例方法即可

B *b = [B new];
[b textViewRowsChangeTo:^(NSInteger lines) {
rowCount = lines;
[self remakeConstraint];
}];

最后,这又是一篇How to do的文章。说起来价值不算大。

但我觉得,想快速学一个新东西并且上手用起来,是需要从不断模仿别人写的代码做起的。

就像我第一次看代理,虽然了解大概实现过程,但用起来还是经常会出现忘写XX.delegate = self这看似微不足道的代码的,导致的结果就是调试程序的时候发现代理不起作用,然后排查业务逻辑,看手势事件有没有捕捉到...到最后才会想到排查语法错误。一个小错误导致我效率低下。(这种错误其实是对代理实现原理理解的不够造成的,但对于新手,理解需要时间,而要快速上项目就需要熟记这个实现流程,然后通过大量编码的过程去参悟原理。)

我想说的是,一般调试逻辑bug的时候很少会去想到语法错误,这就要求了我们平时写代码的时候要注意编程的细节,在学习的时候打好基础。有时候为了追求快速实现功能,可以不去深究,知道实现步骤就可以,比如说这个Block回调,这篇文章就可以作为一个模板,每次用的时候都按照这个步骤去做可以保证不出错,可以快速出效果。照着这个写多了,熟练了就自然不会犯低级的语法错误,这对提升效率很有帮助。这也是为什么我坚持记录How to do的文章的原因。

不过另外说起来,How to do的文章还有一个意义,那就是How to do都是有一个步骤顺序的,先干什么,再干什么。这个顺序就很有意义,它能提供一套解决问题的思路,也就是能看出这套语法的设计者是怎么去思考的。从设计者的思路去看语法就为我们后期深入学习理解相关知识提供了一条路子。当然了,具体能看到什么,学到什么还是看个人对编程的理解,也就是我所认为的编程心法。

好了,扯的有点偏,关于Block回调快速上手的方法就是这样了,熟记这个步骤(千万别死记,编码是灵活的),多去敲代码,慢慢就会产生诸如"为什么要写_b_getRowsBlock = block;"的疑问,当产生疑问时,那就说明你熟悉并开始思考语法了。一定要思考,不然注定是当一辈子的码农,而不是程序员。

关于Block的内容还有很多。由于平时Block用的的确少,所以关于这部分的资料我还需要一些时间去消化。后面我会尽量多写Block,感受不同场景下的使用。

最最后,我还记得几个月前我盯着代码发呆然后突然感叹一声:“原来这TM就是面向对象啊”的喜悦呢。(不是不懂,而是有了新的理解)

[Objective-C] Block实现回调和简单的学习思考的更多相关文章

  1. block学习二:使用Block替代回调

    使用Block替代回调,分为三步进行:

  2. 【转】JS回调函数--简单易懂有实例

    JS回调函数--简单易懂有实例 初学js的时候,被回调函数搞得很晕,现在回过头来总结一下什么是回调函数. 我们先来看看回调的英文定义:A callback is a function that is ...

  3. TestNG简单的学习-TestNG运行

    转载:http://topmanopensource.iteye.com/blog/1983735 TestNG简单的学习-TestNG运行 文档来自官方地址: http://testng.org/d ...

  4. Linux简单编程学习心得

    在Linux环境下简单编程学习心得 linux编程过程 在上周的<信息安全设计基础>的课程学习中学习到了在虚拟的linux环境下简单的编程.学习过程中接触到了vim.gcc和gcd在实验楼 ...

  5. 20145217《网络对抗》 MAL_简单后门学习总结

    20145217<网络对抗> MAL_简单后门学习总结 实践内容: 1.netcat的应用 2.socat的应用 3.meterpreter的应用 知识点学习总结 后门程序一般是指那些绕过 ...

  6. 【转】block一点也不神秘————如何利用block进行回调

    我们在开发中常常会用到函数回调,你可以用通知来替代回调,但是大多数时候回调是比通知方便的,所以何乐而不为呢?如果你不知道回调使用的场景,我们来假设一下: 1.我现在玩手机 2.突然手机没有电了 3.我 ...

  7. [置顶] block一点也不神秘————如何利用block进行回调

    我们在开发中常常会用到函数回调,你可以用通知来替代回调,但是大多数时候回调是比通知方便的,所以何乐而不为呢?如果你不知道回调使用的场景,我们来假设一下: 1.我现在玩手机 2.突然手机没有电了 3.我 ...

  8. 如何结合场景利用block进行回调

    我们在开发中常常会用到函数回调,你可以用通知来替代回调,但是大多数时候回调是比通知方便的,所以何乐而不为呢?如果你不知道回调使用的场景,我们来假设一下: 1.我现在玩手机 2.突然手机没有电了 3.我 ...

  9. block一点也不神秘————如何利用block进行回调

    我们在开发中常常会用到函数回调,你可以用通知来替代回调,但是大多数时候回调是比通知方便的,所以何乐而不为呢?如果你不知道回调使用的场景,我们来假设一下: 1.我现在玩手机 2.突然手机没有电了 3.我 ...

随机推荐

  1. RESTful SOA与DDD(领域驱动设计)

    视频地址:http://www.infoq.com/presentations/RESTful-SOA-DDD 作者的一个DDD采访:http://www.informit.com/articles/ ...

  2. Android面试题(1)

    1.  Java语言基本数据类型有哪些?分别占用的内存空间是多少? 答: byte(1字节),boolean(1字节),char(2字节),short(2字节),int(4字节),float(4字节) ...

  3. logstash-3-输出到es中

    之前测试 filebeat和logstash的时候, 使用的是stdout标准输出, 现在我们想把数据输出到es中去, 1, 首先需要一个es: 修改配置文件 后台启动 ./bin/elasticse ...

  4. 面试:C++二叉树遍历(递归/非递归)

    #include <vector> #include <stack> #include <queue> using namespace std; struct Tr ...

  5. Flutter踩坑日记:Tab导航栏保持子页面状态

    最近应邀票圈小伙伴躺坑Flutter,项目初步雏形完结.以原来的工具链版本为基础做了Flutter版本,不过后面还是需要优化下项目接入Redux,以及扩展一些Native方法. 这里记录一下在开发过程 ...

  6. linux下的重命名

    mv oldname newname 显然,移动命令可以实现重命名. 而rename命令通常用于批量文件的重命名.

  7. mysql进行时

    1. 安装 参考 2. 远程连不上数据库 远程连接mysql时,提示“is not allowed to connect to this MySQL server” 解决(授权法): GRANT AL ...

  8. UVa Dropping Balls

    题目链接: https://cn.vjudge.net/problem/UVA-679 /* 问题 输入完全二叉树的层数D和有几个小球滚落,计算最后一个小球落入的叶子结点的小号. 解题思路 直接模拟超 ...

  9. redis缓存工具类,提供序列化接口

    1.序列化工具类 package com.qicheshetuan.backend.util; import java.io.ByteArrayInputStream; import java.io. ...

  10. 学习Memcached:2基本应用之控制台使用

    1.首先新建一个控制台应用. 2.将下载好需要引用的Memcached的Dll导入进来. 3.前期准备工作就结束了,其实很简单,memcache的配置使用是挺简单.下面就是写代码了. using Me ...