首页 > 代码库 > Block
Block
Block的实质是Objective-C的对象
1. Block的使用
Block的使用其实相当于代理,一般是跨越两个类来使用的。比如作为property属性或者作为方法的参数,这样就能跨越两个类了(参考:“Block全面分析”)
如下为声明为property属性的方法
typedef void (^blk_t)(void); @property (nonatomic, copy) blk_t blk;
2.__block关键字的使用
- (void)viewDidLoad { //将Block定义在方法内部 int x = 100; void (^sumXAndYBlock)(int) = ^(int y){ x = x+y; printf("new x value is %d",x); }; sumXAndYBlock(50); }
上面在block内对x进行赋值,会提示错误,需要把x的声明改为如下:
__block int x = 100;
3. 截获自动变量
int main() { int dmy = 256; int val = 10; const char *fmt = "val = %d\n"; //编译后 bound by copy void (^blk)(void) = ^{printf(fmt,val);}; //在此截获,后面调用时调用的是此处的值 val = 2; fmt = "These values were changed. val = %d\n"; blk(); return 0; }
(1)所谓“截获自动变量值”意味着在执行Block语法时,Block语法表达式所使用的自动变量值被保存到Block的结构体实例(即Block自身__main_block_impl_0)中。
(2)Block不能截获C语言数组类型的自动变量。
(3)Block中使用自动变量后,在Block的结构体实例中重写该自动变量也不会改变原先截获的自动变量(实现上)。
4. 避免循环引用
@weakify(self); [[MTANetworkManager instance] addResMiddleware:^(id object, MTAMiddlewareNextBlock next) { @strongify(self); [self refreshTokenWithTask:task]; }];
上面的代码中,self拥有block,block中又使用了self,因此需要使用@weakify(self)和@strongify(self)来避免循环引用。
原理(参考“strongify & weakify”):
After @strongify
is called, self
will have a different pointer address inside the block than it will outside the block. That‘s because @strongify
declares a new local variable called self
each time. (This is why it suppresses the -Wshadow
warning, which will “warn whenever a local variable shadows another local variable.”) It‘s worth reading and understanding the implementation of these functions. So even though the names are the same, treat them as separate strong
references.
However, remember that after your first use of @strongify
, self
will refer to local, stack variables.
Block