《Objective-C高級編程》Blocks 閱讀筆記 item10(copy/release實例方法)

《Objective-C高級編程》Blocks 閱讀筆記系列

《Objective-C高級編程》Blocks 閱讀筆記 item1(Blocks概要和模式)
《Objective-C高級編程》Blocks 閱讀筆記 item2(Block的實質(zhì))
《Objective-C高級編程》Blocks 閱讀筆記 item3(截獲自動變量值)
《Objective-C高級編程》Blocks 閱讀筆記 item4(__block說明符)
《Objective-C高級編程》Blocks 閱讀筆記 item5(Block存儲域)
《Objective-C高級編程》Blocks 閱讀筆記 item6(__block變量存儲域)
《Objective-C高級編程》Blocks 閱讀筆記 item7(截獲對象)
《Objective-C高級編程》Blocks 閱讀筆記 item8(__block變量和對象)
《Objective-C高級編程》Blocks 閱讀筆記 item9(Block循環(huán)引用)
《Objective-C高級編程》Blocks 閱讀筆記 item10(copy/release實例方法)

2.3 Blocks的實現(xiàn)

2.3.9 copy/release

*** ARC無效時,需要用copy實例方法手動將Blocl從棧復(fù)制到堆,用release實例方法來釋放復(fù)制的Block。 ***

void (^blk_on_heap)(void) = [blk_on_stack copy];

[blk_on_heap release];

*** 只要Block有一次復(fù)制并配置在堆上,就可通過retain實例方法持有。***

[blk_on_heap retain];

*** 但是,對于配置在棧上的Block調(diào)用retain實例方法則不起任何作用。 ***

[blk_on_stack retain];

該源代碼中,雖然對賦值給blk_on_stack的棧上的Block調(diào)用了retain實例方法,但實際上對此源代碼不起任何作用。因此,推薦使用copy實例方法來持有Block(不用retain實例方法)。

由于Block是C語言的擴展,所以在C語言中也可以使用Block語法。此時使用“Block_copy函數(shù)”“Block_release函數(shù)”代替copy/release實例方法。

void (^blk_on_heap)(void) = Block_copy(blk_on_stack);

Block_release(blk_on_heap);

*** ARC無效時,__block說明符被用來避免Block中的循環(huán)引用。***
這是由于當(dāng)Block從棧復(fù)制到堆時,若Block使用的變量為附有__block說明符的id類型或?qū)ο箢愋偷淖詣幼兞浚粫籸etain;若Block使用的變量為沒有__block說明符的id類型或?qū)ο箢愋偷淖詣幼兞浚瑒t被retain。

typedeft void (^blk_t)(void);

@interface MyObject : NSObject
{
    blk_t blk_;
}
@end

@implementation MyObject
- (id)init
{
    self = [super init];
    
    blk_ = ^{NSLog(@"self = %@", self);};
    
    return self;
}

- (void)dealloc
{
    NSLog(@"dealloc");
}
@end

int main()
{
    id o = [[MyObject alloc] init];
    
    NSLog(@"%@", o);
    
    return 0;
}

該源代碼無論ARC有效還是無效都會引起循環(huán)引用,Block持有self,self持有Block。

可使用__block變量來避免出現(xiàn)該問題。

- (id)init
{
    self = [super init];
    
    __block id blockSelf = self; 
    
    blk_ = ^{NSLog(@"self = %@", blockSelf);};
    
    return self;
}

這時,由于Block使用__block變量,所以不會被retain。

注意

  • ARC有效時,__block說明符和__unsafe_unretained修飾符一起使用,來解決附有__unsafe_unretained修飾符的自動變量不能retain的問題。
  • __block說明符在ARC有效無效時的用途有很大的區(qū)別,所以,在使用__block說明符必須清楚源代碼是在ARC有效還是無效的情況下編譯。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容