- (存在栈中的block)和(函数)在运行完后就会销毁
- 在ARC中block可以用strong或copy都行,MRC则需用copy修饰
- block是一个数据类型, 多用于参数传递, 代替代理方法, (有多个参数需要传递或者多个代理方法需要实现还是推荐使用代理方法), 少用于当做返回值传递.
- block是一个OC对象, 它的功能是保存代码片段, 预先准备好代码, 并在需要的时候执行.
- 使用block代码块应注意内部循坏引用, 导致循环引用应在block定义前加上__weak声明:
__weak typeof(<#obj#>) weak<#name#> = <#name#>;
在Xcode里输入inlineblock可以快速补全block定义:
<#returnType#> (^<#blockName#>) (<#parameterTypes#>) = ^ (<#parameters#>){ <#statements#> };
returnType : 返回值类型
blockName : block命名parameterTypes : 参数类型
parameters : 参数声明
block使用 <#returnType#> (^<#blockName#>) (<#parameterTypes#>);
如: @property (copy, nonatomic) void (^block)(int);
在Block中, 如果只使用全局或静态变量或不使用外部变量, 那么Block块的代码会存储在全局区;
如果使用了外部变量, 在ARC中, Block块的代码会存储在堆区; 在MRC中, Block快的代码会存储在栈区;
block默认情况下不能修改外部变量, 只能读取外部变量:
在ARC中, 外部变量存在堆中, 这个变量在Block块内与在Block块外地址相同;
外部变量存在栈中, 这个变量会被copy到为Block代码块所分配的堆中;
在MRC中, 外部变量存在堆中, 这个变量在Block块内与Block块外相同;
外部变量存在栈中, 这个变量会被copy到为Block代码块所分配的栈中;
如果需要修改外部变量, 需要在外部变量前面声明 __block:
在ARC中, 外部变量存在堆中, 这个变量在Block块内与Block块外地址相同;
外部变量存在栈中, 这个变量会被转移到堆区, 不是复制, 是转移.
在MRC中, 外部变量存在堆中, 这个变量在Block块内与Block块外地址相同;
外部变量存在栈中, 这个变量在Block块内与Block块外地址相同;
ARC && 外部变量在堆中:
1.__weak修饰,不会强引用,但是有可能变量会提前释放,可以在block内部用__strong重新修饰(不会循环引用,且会在执行完block后自动释放).
且block内外不是同一个变量,只是指向的地址相同.
2.__strong是强引用(可以在block结束前置为nil来避免循环引用),且声明block后变量本身地址会变化,且block内外的是同一个变量,所以要注意带来的隐患
网友评论