ios 全面解析block
typedef int(^MyBlock)();
void cFun(void(^blockName1)(), MyBlock blockName2){
//兩種寫法都可以
}
-(void)ocFun:(void(^)())blockName1 andOtherBlock:(MyBlock)blockName2{
//注意第一種寫法的特別之處, OC函式要求變數型別和形參名分開, 所以寫法和C不同
}
在oc中呼叫cFun,直接cFun就可以了,但是ocFun就需要 [self ocFun].
block是一個特殊的OC物件, 它建立在棧上, 而不是堆上, 這麼做一個是為效能考慮,還有就是方便訪問區域性變數.
預設情況下block使用到的區域性變數都會被保留,而不是複製.
所以它無法改變區域性變數的值.
如果在變數面前加上__block, 那就是告訴編譯器, 當吧快從棧移動到堆上的時候,要把變數也複製一份放到堆上, 這樣我們就可以改變變數.
另外塊是在棧上分配的, 所以一旦離開作用域, 就會釋放, 因此如果你要把快用在別的地方, 必須要複製一份.
所以在屬性定義一個快的時候需要使用copy: @property (nonatomic, copy) void (^onTextEntered)(NSString *enteredText);
塊是不能保留的, retain對塊沒有意義
ARC下Block何時會從棧自動被複制到堆, 以及__block和__weak的使用問題
由於Block是預設建立在棧上, 所以如果離開方法作用域, Block就會被丟棄, 在非ARC情況下, 我們要返回一個Block ,需要 [Block copy];
在ARC下, 以下幾種情況, Block會自動被從棧複製到堆:
1.被執行copy方法
2.作為方法返回值
3.將Block賦值給附有__strong修飾符的id型別的類或者Blcok型別成員變數時
4.在方法名中含有usingBlock的Cocoa框架方法或者GDC的API中傳遞的時候.
對於非ARC下, 為了防止迴圈引用, 我們使用__block來修飾在Block中實用的物件:
__block id blockSelf=self;
self.block=^{
NSLog(@"%@",blockSelf); //在非ARC下對於棧上的_block物件, Block不會對其複製, 僅僅使用, 不會增加引用計數.
};
對於ARC下, 為了防止迴圈引用, 我們使用__weak來修飾在Block中實用的物件:
__weak id weakSelf=self;
self.block=^{
NSLog(@"%@",weakSelf);
};
如果要在ARC下, 為了防止迴圈引用, 使用__block來修飾在Block中實用的物件,仍然會被retain, 所以需要多做一些設定
__block id blockSelf=self;
self.block=^{
NSLog(@"%@",blockSelf);
blockSelf=nil;
};
並且一定要執行一次block();
這樣就使block斷開了與blockSelf的持有關係, 這是使用__block是為了允許在block修改其值.
void cFun(void(^blockName1)(), MyBlock blockName2){
//兩種寫法都可以
}
-(void)ocFun:(void(^)())blockName1 andOtherBlock:(MyBlock)blockName2{
//注意第一種寫法的特別之處, OC函式要求變數型別和形參名分開, 所以寫法和C不同
}
在oc中呼叫cFun,直接cFun就可以了,但是ocFun就需要 [self ocFun].
block是一個特殊的OC物件, 它建立在棧上, 而不是堆上, 這麼做一個是為效能考慮,還有就是方便訪問區域性變數.
預設情況下block使用到的區域性變數都會被保留,而不是複製.
所以它無法改變區域性變數的值.
如果在變數面前加上__block, 那就是告訴編譯器, 當吧快從棧移動到堆上的時候,要把變數也複製一份放到堆上, 這樣我們就可以改變變數.
另外塊是在棧上分配的, 所以一旦離開作用域, 就會釋放, 因此如果你要把快用在別的地方, 必須要複製一份.
所以在屬性定義一個快的時候需要使用copy: @property (nonatomic, copy) void (^onTextEntered)(NSString *enteredText);
塊是不能保留的, retain對塊沒有意義
ARC下Block何時會從棧自動被複制到堆, 以及__block和__weak的使用問題
由於Block是預設建立在棧上, 所以如果離開方法作用域, Block就會被丟棄, 在非ARC情況下, 我們要返回一個Block ,需要 [Block copy];
在ARC下, 以下幾種情況, Block會自動被從棧複製到堆:
1.被執行copy方法
2.作為方法返回值
3.將Block賦值給附有__strong修飾符的id型別的類或者Blcok型別成員變數時
4.在方法名中含有usingBlock的Cocoa框架方法或者GDC的API中傳遞的時候.
對於非ARC下, 為了防止迴圈引用, 我們使用__block來修飾在Block中實用的物件:
__block id blockSelf=self;
self.block=^{
NSLog(@"%@",blockSelf); //在非ARC下對於棧上的_block物件, Block不會對其複製, 僅僅使用, 不會增加引用計數.
};
對於ARC下, 為了防止迴圈引用, 我們使用__weak來修飾在Block中實用的物件:
__weak id weakSelf=self;
self.block=^{
NSLog(@"%@",weakSelf);
};
如果要在ARC下, 為了防止迴圈引用, 使用__block來修飾在Block中實用的物件,仍然會被retain, 所以需要多做一些設定
__block id blockSelf=self;
self.block=^{
NSLog(@"%@",blockSelf);
blockSelf=nil;
};
並且一定要執行一次block();
這樣就使block斷開了與blockSelf的持有關係, 這是使用__block是為了允許在block修改其值.
相關文章
- iOS探索:Block解析淺談iOSBloC
- iOS中Block實現原理的全面分析iOSBloC
- iOS動畫全面解析iOS動畫
- iOS Block探究iOSBloC
- iOS block巢狀block中weakify的使用iOSBloC巢狀
- iOS - Block探究系列一iOSBloC
- iOS block 反向傳值iOSBloC
- iOS Block淺淺析iOSBloC
- iOS中Block的用法,示例,應用場景,與底層原理解析(這可能是最詳細的Block解析)iOSBloC
- iOS Block學習筆記iOSBloC筆記
- iOS - 對 block 實現的探究iOSBloC
- this 全面解析
- this全面解析
- 探索iOS中Block的實現原理iOSBloC
- iOS-block本質是什麼?iOSBloC
- iOS底層原理 - Block本質探究iOSBloC
- this 全面解析(一)
- this全面解析(二)
- JavaScriptCore全面解析JavaScript
- 區塊鏈(Block Chain)結構解析區塊鏈BloCAI
- iOS Xcode全面剖析iOSXCode
- iOS Block傳值、代理傳值、通知中心iOSBloC
- iOS 中的 block 是如何持有物件的iOSBloC物件
- iOS奇思妙想之使用block替代通知iOSBloC
- iOS-block迴圈引用詳解和應用iOSBloC
- iOS | 用於解決迴圈引用的block timeriOSBloC
- 全面解析 qiankun 原始碼原始碼
- Python_類全面解析Python
- 全面解析JavaScript中this指向JavaScript
- Redux 原始碼全面解析Redux原始碼
- Java 註解全面解析Java
- Java註解全面解析Java
- Android之Activity全面解析Android
- iOS – XML解析iOSXML
- iOS 動畫之Spring動畫、Block動畫、GIF圖iOS動畫SpringBloC
- 異常處理全面解析
- 結果集 (ResultSet)全面解析
- Android Service最全面的解析Android
- 全面解析Flutter Platform Channel原理FlutterPlatform