__block 與 __weak的區(qū)別理解

Blocks理解:
Blocks可以訪問局部變量,但是不能修改
如果修改局部變量,需要加__block

 __block int multiplier = 7;
     int (^myBlock)(int) = ^(int num) {
         multiplier ++;//這樣就可以了
         return num * multiplier;
     };

2、如果局部變量是數(shù)組或者指針的時候只復制這個指針,兩個指針指向同一個地址,block只修改指針上的內(nèi)容。如:

NSMutableArray *mArray = [NSMutableArray arrayWithObjects:@"a",@"b",@"abc",nil];
    NSMutableArray *mArrayCount = [NSMutableArray arrayWithCapacity:1];
    [mArray enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock: ^(id obj,NSUInteger idx, BOOL *stop){
        [mArrayCount addObject:[NSNumber numberWithInt:[obj length]]];
    }];
   
    NSLog(@"%@",mArrayCount);

例子里面確實沒有修改mArrayCount這個局部變量啊。mArrayCount是一個指針,指向一個可變長度的數(shù)組。在block里面,并沒有修改這個指針,而是修改了這個指針指向的數(shù)組。換句話說,mArrayCount是一個整數(shù),保存的是一塊內(nèi)存區(qū)域的地址,在block里,并沒有改變這個地址,而是讀取出這個地址,然后去操作這塊地址空間的內(nèi)容。

這是允許的,因為聲明block的時候實際上是把當時的臨時變量又復制了一份,在block里即使修改了這些復制的變量,也不影響外面的原始變量。即所謂的閉包。

但是當變量是一個指針的時候,block里只是復制了一份這個指針,兩個指針指向同一個地址。所以,在block里面對指針指向內(nèi)容做的修改,在block外面也一樣生效。

__weak __typeof(&*self)weakSelf =self; 等同于
__weak UIViewController *weakSelf =self;

為什么不用__block 是因為通過引用來訪問self的實例變量 ,self被retain,block也是一個強引用,引起循環(huán)引用,用__week是弱引用,當self釋放時,weakSelf已經(jīng)等于nil。

擴展:NSTimer注意避免循環(huán)引用的地方,需要找個合適的時機和地方來 invalidate timer

在引用計數(shù)的環(huán)境里面,默認情況下當你在block里面引用一個Objective-C對象的時候,該對象會被retain。當你簡單的引用了一個對象的實例變量時,它同樣被retain。但是被__block存儲類型修飾符標記的對象變量不會被retain

注意:在垃圾回收機制里面,如果你同時使用__weak和__block來標識一個變量,那么該block將不會保證它是一直是有效的。 如果你在實現(xiàn)方法的時候使用了block,對象的內(nèi)存管理規(guī)則更微妙:也是(__weak與__block區(qū)別:)

1、如果你通過引用來訪問一個實例變量,self會被retain。
2、如果你通過值來訪問一個實例變量,那么變量會被retain

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

相關閱讀更多精彩內(nèi)容

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