iOS知識(shí)整理-Block

Block是將函數(shù)及其執(zhí)行上下文封裝起來(lái)的對(duì)象

變量截獲

局部變量截獲 是值截獲

NSInteger num = 3;
NSInteger(^block)(NSInteger) = ^NSInteger(NSInteger n){
       return n*num;
};
num = 1;
NSLog(@"%zd",block(2));  
// 輸出是6而不是2,原因就是對(duì)局部變量num的截獲是值截獲。
NSMutableArray * arr = [NSMutableArray arrayWithObjects:@"1",@"2", nil];
void(^block)(void) = ^{
        NSLog(@"%@",arr);//局部變量
        [arr addObject:@"4"];
    };
[arr addObject:@"3"];
arr = nil;
block();
// 打印為1,2,3.因?yàn)閎lock內(nèi)部會(huì)截獲arr,且引用修飾符相同。

?
局部靜態(tài)變量截獲 是指針截獲

static  NSInteger num = 3;
NSInteger(^block)(NSInteger) = ^NSInteger(NSInteger n){
    return n*num;
};
num = 1;
NSLog(@"%zd",block(2));
// 輸出為2,意味著num = 1這里的修改num值是有效的,即是指針截獲。
// 同樣,在block里去修改變量m,也是有效的。

?
全局變量,靜態(tài)全局變量截獲:不截獲,直接取值。

static NSInteger num3 = 300;
NSInteger num4 = 3000;
- (void)blockTest {
    void(^block)(void) = ^{
        NSLog(@"%zd",num3);//全局變量
        NSLog(@"%zd",num4);//全局靜態(tài)變量
    };
    block();
}
// 300, 3000

Block循環(huán)引用

當(dāng)self持有Block,Block中又使用self時(shí),就會(huì)產(chǎn)生循環(huán)引用。
解決辦法:

  1. __weak來(lái)修飾self。當(dāng)self有可能被釋放時(shí),可以在block內(nèi)部再用__strong生成strongSelf;
    __weak typeof(self) weakSelf = self;
    self.setAlertBlock = ^(NSString *status) {
        __strong typeof(weakSelf) strongSelf = weakSelf;
    };
  1. 在block內(nèi)部使用完self后,將其置為nil,但這種方式有個(gè)問(wèn)題,如果block一直不被調(diào)用,那么循環(huán)引用將一直存在。所以,我們最好還是用__weak來(lái)修飾self。

參考:Block原理、Block變量截獲、Block的三種形式、__block

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容