概述
iOS SDK 4.0开始,Apple引入了block这一特性,它是带有自动变量的匿名函数。先来看看block的经典用法:
1 | [UIView animateWithDuration:0.3 animations:^{ |
定义block变量
关于block的语法,请使劲戳这里-> 语法
返回值类型 (^变量名)(参数类型 …) = ^ 返回值类型 (参数类型 入参名 …) {return 返回值}
1 | // even or uneven |
返回值->BOOL
名称-> isInputEven
参数-> int
入参-> input
全局变量
1 | ... |
局部变量
1 | int x = 25; |
typedef block
1 | typedef int (^blockName)(int param); |
Swift 逃逸闭包(@escaping)
逃逸闭包:当函数执行结束后,才去调用函数内部的闭包,叫做逃逸闭包@escaping
非逃逸闭包:当函数执行过程中,执行的函数内部的闭包,叫做非逃逸闭包 @noescape
从 Swift 3开始, non-escaping 闭包闭包默认声明为 non-escaping , 如果你想让参数闭包逃逸的话, 你需要加上一个 @escaping 去修饰类型. 上代码:
1 |
|
block 内存
_NSConcreteGlobalBlock 静态区(全局区)block:这是一种特殊的bloclk,因为不引用外部变量或引用全局变量、静态变量而存在。另外,作为静态区的对象,它的释放是有操作系统控制的。
_NSConcreteStackBlock 栈区block:位于内存的栈区,一般作为函数的参数出现。
_NSConcreteMallocBlock 堆区block:位于内存的堆区,一般作为对象的property出现。
如果一个blcok引用了外部变量是栈block,则其不引用外部变量就成为了静态blcok。
如果一个block引用了外部变量是堆block,则其不引用外部变量就成为了静态block。
深入 请看霜神: 深入研究Block捕获外部变量和__block实现原理 和 深入研究Block用weakSelf、strongSelf、@weakify、@strongify解决循环引用
笔记
- block的实质是什么?一共有几种block?都是什么情况下生成的?
- 为什么在默认情况下无法修改被block捕获的变量? __block都做了什么?
-
- 自动变量是以值传递方式传递到Block的构造函数里面去的。Block只捕获Block中会用到的变量。由于只捕获了自动变量的值,并非内存地址,所以Block内部不能改变自动变量的值
- 一是传递内存地址指针到Block中(例:NSMutableString拼接),二是改变存储区方式(__block)。
- 模拟一下循环引用的一个情况?block实现界面反向传值如何实现?