1.Block注意事項(xiàng)
- 在block內(nèi)部可以訪問block外部的變量
int a = 10;
void (^myBlock)() = ^{
NSLog(@"a = %i", a);
}
myBlock();
輸出結(jié)果: 10
- block內(nèi)部也可以定義和block外部的同名的變量(局部變量),此時(shí)局部變量會(huì)暫時(shí)屏蔽外部
int a = 10;
void (^myBlock)() = ^{
int a = 50;
NSLog(@"a = %i", a);
}
myBlock();
輸出結(jié)果: 50
- 默認(rèn)情況下, Block內(nèi)部不能修改外面的局部變量
int b = 5;
void (^myBlock)() = ^{
b = 20; // 報(bào)錯(cuò)
NSLog(@"b = %i", b);
};
myBlock();
- Block內(nèi)部可以修改使用__block修飾的局部變量
__block int b = 5;
void (^myBlock)() = ^{
b = 20;
NSLog(@"b = %i", b);
};
myBlock();
輸出結(jié)果: 20
- 為什么不加__block不能在block中修改外界變量的值
int a = 10;
void (^myBlock)() = ^{
a = 10;
NSLog(@"a = %i", a);
};
myBlock();
int a = 10; // 如果沒有添加__block是值傳遞
void (*myBlock)() = &__main_block_impl_0( __main_block_func_0, &__main_block_desc_0_DATA, a);
(myBlock)->FuncPtr)(myBlock);
- 為什么加了__block就可以在block中修改外界變量的值
a = 10; // 如果加上__block之后就是地址傳遞, 所以可以在block中修改外界變量的值
void (*myBlock)() = &__main_block_impl_0(__main_block_func_0, &__main_block_desc_0_DATA, &a, 570425344);
__block int a = 10;
void (^myBlock)() = ^{
a = 10;
NSLog(@"a = %i", a);
};
myBlock();
block是存儲(chǔ)在堆中還是棧中
默認(rèn)情況下block存儲(chǔ)在棧中, 如果對block進(jìn)行一個(gè)copy操作, block會(huì)轉(zhuǎn)移到堆中
如果block在棧中, block中訪問了外界的對象, 那么不會(huì)對對象進(jìn)行retain操作
但是如果block在堆中, block中訪問了外界的對象, 那么會(huì)對外界的對象進(jìn)行一次retain
如果在block中訪問了外界的對象, 一定要給對象加上__block, 只要加上了__block, 哪怕block在堆中, 也不會(huì)對外界的對象進(jìn)行retain
如果是在ARC開發(fā)中就需要在前面加上__weak
__block Person *p = [[Person alloc] init]; // 1如果在做iOS開發(fā)時(shí), 在ARC中不這樣寫容易導(dǎo)致循環(huán)引用
Person *p = [[Person alloc] init];
__weak Person *weakP = p;