__block 和 __weak的區別

Blocks理解:html

Blocks能夠訪問局部變量,可是不能修改數組

若是修改局部變量,須要加__block閉包

 

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

 

 

二、若是局部變量是數組或者指針的時候只複製這個指針,兩個指針指向同一個地址,block只修改指針上的內容。如:ui

 

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是一個指針,指向一個可變長度的數組。在block裏面,並無修改這個指針,而是修改了這個指針指向的數組。換句話說,mArrayCount是一個整數,保存的是一塊內存區域的地址,在block裏,並無改變這個地址,而是讀取出這個地址,而後去操做這塊地址空間的內容。spa

這是容許的,由於聲明block的時候其實是把當時的臨時變量又複製了一份,在block裏即便修改了這些複製的變量,也不影響外面的原始變量。即所謂的閉包。指針

可是當變量是一個指針的時候,block裏只是複製了一份這個指針,兩個指針指向同一個地址。因此,在block裏面對指針指向內容作的修改,在block外面也同樣生效。code

 

__weak __typeof(&*self)weakSelf =self; 等同於htm

__weak UIViewController *weakSelf =self;對象

爲何不用__block 是由於經過引用來訪問self的實例變量 ,self被retain,block也是一個強引用,引發循環引用,用__week是弱引用,當self釋放時,weakSelf已經等於nil。blog

擴展:NSTimer注意避免循環引用的地方,須要找個合適的時機和地方來 invalidate timer

 

在引用計數的環境裏面,默認狀況下當你在block裏面引用一個Objective-C對象的時候,該對象會被retain。當你簡單的引用了一個對象的實例變量時,它一樣被retain。可是被__block存儲類型修飾符標記的對象變量不會被retain

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

一、若是你經過引用來訪問一個實例變量,self會被retain。
二、若是你經過值來訪問一個實例變量,那麼變量會被retain

 

 

__weak主要適用於避免循環引用    , 如何避免請見博文:http://www.cnblogs.com/MasterPeng/p/5311911.html

相關文章
相關標籤/搜索