Blocks理解: Blocks可以訪問局部變數,但是不能修改 如果修改局部變數,需要加__block 2、如果局部變數是數組或者指針的時候只複製這個指針,兩個指針指向同一個地址,block只修改指針上的內容。如: 例子裡面確實沒有修改mArrayCount這個局部變數啊。mArrayCount是一 ...
Blocks理解:
Blocks可以訪問局部變數,但是不能修改
如果修改局部變數,需要加__block
__block int multiplier = 7;
int (^myBlock)(int) = ^(int num) {
multiplier ++;//這樣就可以了
return num * multiplier;
};
2、如果局部變數是數組或者指針的時候只複製這個指針,兩個指針指向同一個地址,block只修改指針上的內容。如:
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里,並沒有改變這個地址,而是讀取出這個地址,然後去操作這塊地址空間的內容。
這是允許的,因為聲明block的時候實際上是把當時的臨時變數又複製了一份,在block里即使修改了這些複製的變數,也不影響外面的原始變數。即所謂的閉包。
但是當變數是一個指針的時候,block里只是複製了一份這個指針,兩個指針指向同一個地址。所以,在block裡面對指針指向內容做的修改,在block外面也一樣生效。
__weak __typeof(&*self)weakSelf =self; 等同於
__weak UIViewController *weakSelf =self;
為什麼不用__block 是因為通過引用來訪問self的實例變數 ,self被retain,block也是一個強引用,引起迴圈引用,用__week是弱引用,當self釋放時,weakSelf已經等於nil。
擴展:NSTimer註意避免迴圈引用的地方,需要找個合適的時機和地方來 invalidate timer
在引用計數的環境裡面,預設情況下當你在block裡面引用一個Objective-C對象的時候,該對象會被retain。當你簡單的引用了一個對象的實例變數時,它同樣被retain。但是被__block存儲類型修飾符標記的對象變數不會被retain
註意:在垃圾回收機制裡面,如果你同時使用__weak和__block來標識一個變數,那麼該block將不會保證它是一直是有效的。 如果你在實現方法的時候使用了block,對象的記憶體管理規則更微妙:也是(__weak與__block區別:)
1、如果你通過引用來訪問一個實例變數,self會被retain。
2、如果你通過值來訪問一個實例變數,那麼變數會被retain
__weak主要適用於避免迴圈引用 , 如何避免請見博文:http://www.cnblogs.com/MasterPeng/p/5311911.html