为什么block会造成循环应用呢?
如果没有__weak修饰,block会把对象从栈copy到堆区,block结束的时候无法销毁。如果有__weak修饰,则只是copy了一个指针,block结束的时候就销毁了。
总结:Block的几种形式 分为全局Block(_NSConcreteGlobalBlock)、栈Block(_NSConcreteStackBlock)、堆Block(_NSConcreteMallocBlock)三种形式
一.其中栈Block存储在栈(stack)区,堆Block存储在堆(heap)区,全局Block存储在已初始化数据(.data)区
二.如果对栈Block进行copy,将会copy到堆区,对堆Block进行copy,将会增加引用计数,对全局Block进行copy,因为是已经初始化的,所以什么也不做。
1、不使用外部变量的block是全局block
NSLog(@"%@",[^{
NSLog(@"globalBlock");
}class]);
//输出 __NSGlobalBlock__
//2、使用外部变量并且未进行copy操作的block是栈block
NSIntegernum =10;
NSLog(@"%@",[^{
NSLog(@"stackBlock:%zd",num);
}class]);
//输出 __NSGlobalBlock__
//日常开发常用于这种情况:
[self testWithBlock:^{
NSLog(@"----%ld",(long)num);
}];
//3、对栈block进行copy操作,就是堆block,而对全局block进行copy,仍是全局block
NSIntegernums =10;
void(^mallocBlock)(void) = ^{
NSLog(@"stackBlock:%zd",nums);
};
NSLog(@"mallocBlock:%@",[mallocBlockclass]);
__block typeof(self) weakSelf = self;
_testBlock = ^{
NSLog(@"%@",weakSelf);
};
_testBlock();
//4.Block捕获变量 输出age:10,num:11
autointage =10;
staticintnumss =25;
void(^Block)(void) = ^{
NSLog(@"age:%d,num:%d",age,numss);
};
age =20;
numss =11;
Block();
}
- (void)testWithBlock:(dispatch_block_t)block {
block();
NSLog(@"===%@",[blockclass]);
}