美文网首页
iOS学习之彻底搞清楚Block

iOS学习之彻底搞清楚Block

作者: 北你妹的风 | 来源:发表于2018-03-07 15:50 被阅读10次

    Block介绍

    在Objective-C中,Block是C语言扩充的功能。一句话总结Block就是:带有局部变量的匿名函数。实际上,Block语法在其他语言中也有,在Pythonh、LISP语言中叫Lambda(java 8也引入了),JavaScript中叫Anonymous Function,这种语言概念叫闭包(Closure)。

    举个简单的例子:^(int count){NSLog("%d",count)},这就是一个简单的Block表达式。它没有函数名字,带有^符合。Block语法的范式如下:

    ^  返回值类型  参数列表  表达式

    ^ int (int  count){return count+1}

    这其中的返回值可以省略:

    ^  返回值类型  参数列表  表达式

    此时,如果表达式总return 语句时,就使用该返回值的类型。没有return语句时就默认为void类型,表达式如下:

    ^ (int  count){return count+1}

    Block创建

    可以使用typedef关键字,简便易读地声明一个Block变量,举例如下:

    typedef int (^addMethodBlock)(int),这行代码声明了一个返回值为int类型,名字为addMethodBlock,参数为int类型的Block变量。然后可以给该变量赋值:

    addMethodBlock=^ (int  count){return count+1};

    Block访问

    Block体内访问局部变量,是copy变量的值,也就是说,Block体内访问局部变量,使用的是Block声明时变量的值,之后发生变化,Block体内依然保持不变。

    Block体内不能修改局部变量的值,如果想要在Block体内修改,则需要在局部变量前面加入__block修饰符。

    Block访问static修饰的变量时,直接读取变量的最新值,而不是在Block声明时候的值

    为防止循环引用,需要在Block引用对象变量的时候加入以下代码

    __weak typeof(self) weakSelf=self;

    然后在block体里面用weakSelf来访问self里面的属性。

    Block分类

    什么,Block还有分类?是的,根据Block在内存中不同的位置,Block可以分为三类:

    NSGloabBlock,NSStackBlock,NSMallocBlock

    本质上,Block也是Objective-C的对象。有的对象存储在堆上,有的对象存储在栈上。存储在栈上的Block对象,属于NSStackBlock类型;存储在堆上的Block对象,属于NSMallocBlock类型;存储在程序的数据区域的Block对象,属于NSGloabBlock类型。

    第一种,不需要在运行时改变行为的block,不需要放在堆或栈上,一个很简单的判别方法就是,是否引用外部变量

    第二种,block是在栈上生成的,离开栈的作用域,block就无效了。在MRC环境下,需要手动的进行copy才能脱离栈使用。在ARC下,编译器自动进行copy操作

    第三种,block是在堆上生成的,在第二种,copy过之后的block其实就是位于堆上,即变成了NSMallocBlock

    相关文章

      网友评论

          本文标题:iOS学习之彻底搞清楚Block

          本文链接:https://www.haomeiwen.com/subject/esvjfftx.html