
在OC中习惯用block来传值,而swift中,block被重新定义了一下,叫闭包;
使用的技巧: 谁定义谁传值;
案例使用A、B控制器:
1~4步在B中执行,最后在A中执行;
- B控制器:
1-定义
格式: typealias 闭包名称 = (参数名称: 参数类型) -> 返回值类型
typealias block = (str: String) -> void
2- 声明
var callBackBlock = block()
3- 赋值
需要定义一个方法,参数是和block类型一致得闭包,并赋值给block
```
func callBackFunction ( block: (str: String) -> Void ) {
callBackBlock = block
}
```
4- 传值
func buttonClick () { //需要传值的方法
if callBackBlock != nil {
callBackBlock!( "传这个值给A") //注意,这里是使用属性传值,不是方法
}
}
5 - A控制器中
BcallBackFunction { (str) in
print("这里使用传过来的值")
}
block?你是说程序块?如果是这样的话,block里面的数组一般情况下生命周期结束的地方是block的后花括弧。你若要延长其生命周期,可以将其定义为静态,这样外部就可以获取了。或者函数里面,提供一个输出参数作为提取接口也行。
前言:最近看了好多block相关的东西,block在项目中很常见,想必大家也都比较熟悉,可是,细细想下,又有好多迷惑?为什么会产生循环引用 为什么要用__block __block到底是干什么的如果你也有类似的困惑,那就跟我一起探究下吧。
首先探究下block的本质,他到底是个啥东东呢?
通过clang编译,我们可以看到block的内存布局,就是一个结构体,里面包含一个我么熟悉的isa指针,显然就是一个oc对象。它的底层结构就是:
通过class方法我们可以看到block有3种类型
NSGlobalBlock : 存放在数据段,没有访问auto变量(局部变量)的block(基本没啥用)
NSStackBlock:存放在栈区,访问了auto变量
NSMallocBlock:存放在堆区,NSStackBlock通过copy,从栈区拷贝到堆区
每一种block被copy后的结果
在ARC环境下,编译器会根据情况自动将栈上的block复制到堆上。
MRC下block属性的建议写法
@property (copy, nonatomic) void (^block)(void);
ARC下block属性的建议写法
@property (strong, nonatomic) void (^block)(void);
@property (copy, nonatomic) void (^block)(void);
当block内部访问了对象类型的趋同变量时
1如果block在栈上,将不会对auto变量产生强引用
2如果block被拷贝到堆上
21 会调用block内部的copy函数
22 copy 函数内部会调用_block_object_assign函数
23 _block_object_assign函数会根据auto变量的修饰符(__strong、__weak、__unsafe_unretained)作出相应的 *** 作,形成强引用还是弱引用。
3如果将block从堆上移除
31 会调用block内部的dispose函数
32 dispose函数会调用_Block_object_dispose函数
33 _Block_object_dispose函数自动释放引用的auto变量
当我们想在block内部修改auto变量的时候,总是需要用__block来修饰,这是为什么呢?
31 为什么不能直接在block内部修改auto变量?
当block捕获auto变量的时候,只是获取了它的值,没有获取到它的地址,所以不能进行修改。
那么我们都知道为了解决block无法修改auto变量的问题,需要用到__block来修饰auto变量。
32 那么__block做了什么呢?
被__block 修饰过的auto变量会生成一个结构体
其中__main_block_impl_0是个新的结构体,里面包含一个age指针,这是又是一个结构体__block_byref_age_0,这个结构体的age 才是我们真正传入的值,forwarding也是一样的结构体,他是指向自己的一个指针
总结下__block的使用:
1__block可以用于解决block内部无法修改auto变量值的问题
2 __block不能修饰全局变量,静态变量
3 编译器会将__block变量包装成一个对象
41 当block在栈上,并不会对__block变量产生强引用
42 当block被拷贝到堆时
421 会调用block内部的copy函数
422 copy函数会调用_Block_object_assign函数
423 _Block_object_assign函数会对__block变量行程强引用
43 当block从堆中移除时
431 会调用block内部的disease函数
432 dispose函数内部会调用_Block_object_dispose函数
433 _Block_object_dispose函数会自动释放饮用的__block变量
双方互相持有对方,都无法释放,这就是循环引用
我们经常会想到的解决方案就是用__weak 修饰,下面看看还有哪些解决方法
61 ARC
611 用__weak、__unsafe_unretained解决
612 用__block解决(必须要调用block)
62 MRC
621 用__unsafe_unretained解决
622 用__block解决
看完后,心中好多疑惑大概都解决了,那下面几道面试题来回顾下
1block的本质是什么?
答:封装了函数调用以及调用环境的oc对象
2__block 的作用是什么?有什么需要注意的?
答:作用:__block可以用于解决block内部无法修改auto变量值的问题
注意点: __block不能修饰全局变量,静态变量;在MRC环境中,不会被强引用。
3block的属性修饰为什么是copy,使用block有哪些注意点?
答:block如果没有被copy,就不会在堆上,这样我们无法预知它的生命周期。只有将block被拷贝到堆上,我们才能管理其生命周期,想什么时候释放都行。注:ARC环境下,strong和copy没有区别,为了跟MRC环境中一样,我们喜欢用copy。
需要注意的是,使用block不要产生循环引用。解决循环饮用的方法之前都提到过。
以上就是关于swift中的block全部的内容,包括:swift中的block、为什么在block函数块里面给数组赋值,在之后的输出却是空、Block的原理和使用等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)