1.block不調(diào)用外界變量的情況
- (void)touchesBegan:(NSSet *)touches withEvent: (UIEvent*)event {
//類型變量名=值;
intage = 100;
NSLog(@"====%p",&age);棧區(qū)
//沒有參數(shù)沒有返回值的block
void(^block)() = ^{
NSLog(@"我是block = %p",&age);堆區(qū)
};
//執(zhí)行block
block();
[selftestBlock:block];
NSLog(@"====%p",&age);棧區(qū)
}
- (void)testBlock:(void(^)())block {
block();
}
2.通過__block調(diào)用外部變量的情況
總結(jié):只要通過__block修飾以后,外部變量的地址就變?yōu)槎褏^(qū),在調(diào)用blcok之前值還是棧區(qū)的值,而地址在堆區(qū),當(dāng)調(diào)用了block以后,值變?yōu)樾薷暮蟮闹?而地址也在堆區(qū)
/**
* block修改外部變量`
*/
- (void)testBlock5 {
//類型變量名=值;
__block intage = 100;
NSLog(@"====%p",&age);//棧
//使用__block修飾外部變量時(shí),在定義完成block之后,棧中的外部變量就是一個(gè)擺設(shè),沒有什么亂用了
void(^block)() = ^{
age = 200;
NSLog(@"block中的age = %d",age);// 200
NSLog(@"我是block = %p",&age);//堆
};
使用__block修飾以后,但是沒有調(diào)用block時(shí)候,值不改變,但是地址保存到堆區(qū)了
NSLog(@"====%p",&age);//堆
NSLog(@"age =%d",age);// 100
//執(zhí)行block
//使用__block修飾以后,調(diào)用了block以后,值改變,地址也保存到堆區(qū)了,
block();
NSLog(@"====%p",&age);//堆
NSLog(@"age =%d",age);// 200
}
**結(jié)語(yǔ): **
1.block的三種類型:
全局block :(打印出來__NSGlobalBlock)
無論是ARC還是MRC情況下:block內(nèi)部沒有訪問任何外部變量時(shí),block就是全局block
或者訪問的是static修飾的靜態(tài)變量的時(shí)候,就是全局block
堆block: (打印出來是__NSMallocBlock)block內(nèi)部訪問我外部變量時(shí),(不為靜態(tài)變量時(shí),).block是堆區(qū)block
在MRC環(huán)境下,給block調(diào)用copy方法,會(huì)將棧block拷貝到堆中
C.棧block :(打印出來是__NSStackBlock)
在MRC情況下,block內(nèi)部訪問外部變量時(shí)(不為靜態(tài)變量),block是棧區(qū)block
為什么block要用copy修飾,因?yàn)椴挥胏opy修飾,當(dāng)MRC模式 下,block內(nèi)部訪問外部屬性時(shí)(且屬性不為靜態(tài)屬性時(shí)),block是棧區(qū)block,這樣外界調(diào)用的時(shí)候,就會(huì)報(bào)錯(cuò),使用copy,我們的block無論是ARC還是MRC情況下,肯定是堆區(qū)block,外界調(diào)用就不會(huì)有影響
所以block使用copy是為了兼容MRC的情況,因?yàn)楹芏囗?xiàng)目是ARC和MRC混編.