关于block(四)----block类型
2018-04-26 本文已影响0人
stonly916
block本身是像对象一样可以retain,和release,但是栈block和全局block这些操作都无效,只有堆block操作有效,虽然retainCount始终是1但是内存管理器中仍然增减计数。使用retain也可以,但是block的retain行为默认是用copy的行为实现的,
因为block引用外部变量时默认是声明为栈Block的,为了能够在block的声明域外使用,所以要把block拷贝(copy)到堆,所以说为了block属性声明和实际的操作一致,最好声明为copy。
一、globalBlock无论什么操作都是globalBlock
二、block在什么情况下会copy到mallocBlock?
1.在block中如果有引用外部变量(默认声明为栈Block),且,block被赋值给__strong对象 或者 [block copy]
2.栈Block作为方法、函数的返回值,其实这是一种copy操作
3.GCD或UsingBlock:方法引用block,其实这也是线程或者其他对象强引用了Block
只有stackBlock才有可能变为mallocBlock。
代码1
void(^myBlock)(void) = ^() {
printf("ss");
};
myBlock();
这里的block没有引用外部变量,存储在代码中,为全局类型,NSGlobalBlock
代码2
char *str = "qqq";
void(^myBlock)(void) = ^{
NSLog(@"%s",str);
};
myBlock();
表面看这里的block引用外部变量,存储在栈中,离开作用域就会释放;
但是实际上这里的myBlock是存放在堆中NSMallocBlock,原因是因为这里在将block赋值给myBlock2时,在ARC下系统将block copy到了堆里
代码3
char *str = "aass";
//__NSStackBlock__
NSLog(@"%@",^{printf("%s",str);});
//__NSStackBlock__,直接在栈中被调用
^{printf("%s",str);}();
这里输出的block就是存放在栈里面了,这里没有赋值操作
代码4
char *str = "qqq";
//__NSStackBlock__,这里虽然进行了赋值操作,但是赋值的对象是__weak
__weak Blk blockWeak = ^() {
printf("%s",str);
};
blockWeak();
//__NSMallocBlock__,这里给__strong block对象赋值
__strong Blk blockStrong = ^() {
printf("%s",str);
};
blockStrong();
代码5
__block int h = 9;
//__NSStackBlock__,直接在栈中被调用,因为没有copy也没有给__strong对象赋值
^{h = 11;printf("%d",h);}();
//__NSStackBlock__,直接在栈中被调用,因为没有copy也没有给__strong对象赋值
NSLog(@"%@",^{h = 12;printf("%d",h);});