IOS block 教程
基本就一句話,交代了Block在4.0後被引入,以及我們爲什麼要學習它的一個理由~
二:基本語法
Block可以看成一個語句塊或者是很多時候當做匿名函數來使用。
- (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_4_0); // delay = 0.0, options = 0, completion = NULL
- [ UIView animateWithDuration:10 animations:^{
- NSLog(@"%@,",@"block");
- }];
簡單以這句函數來看。
animations參數接受一個block函數塊。我們直接可以^{};來書寫這個block。
然後看上面函數申明,我們看到animations接受的參數是這麼申明的 (void(^)(void))animations;
這個也好理解,我們知道參數都需要一個申明一個類型比如
(NSTimeInterval)duration。(void(^)(void))其實就是block的一種常見格式的申明。裏面還需要分爲 :
第一個void是指的是block函數無返回,即{}執行玩沒有返回值。(^)是固定規範,表明這是個block類型的。後面的()裏表示block接受參數
當然,這邊是(void)我們知道,不接受參數。
這邊貼一張官方圖
此圖包含了申明和定義。
其實基本綜合一下,我們要了解 三點
1.如何申明一個block函數
int(^testBlock)(int a,int b);
返回值類型 (^block名字)(傳入參數)
2.OC申明一個帶有block參數的函數
-(void)textF:(Bool (^)(id a,id b)) bBlock;
這個就如我們上面看到animations,基本和申明很類似,就是名稱換到外面去了。
(返回類型 (^)(傳入參數))block形參名
然後發現用C代碼申明方法時:
void
dispatch_apply(size_t iterations, dispatch_queue_t queue, void (^block)(size_t));
3.申明後實現一個block函數塊
^(int a,int b){
//code;
}
block基本語法就如上。
在使用block時幾個重要點:
1.block函數外的對象,在block語句塊內只有可讀訪問權限。
2.對外部對象進行__block申明解決了問題1.
3 各類型的變數和block之間的互動:
- 13: extern NSInteger CounterGlobal;
- 14: static NSInteger CounterStatic;
- 15: {
- 16: NSInteger localCounter = 42 ;
- 17: __block char localCharacter;
- 18: void (^aBlock)( void ) = ^( void )
- 19: {
- 20: ++ CounterGlobal ; //可以存取。
- 21: ++ CounterStatic ; //可以存取。
- 22: CounterGlobal = localCounter; //localCounter在block 建立時就不可變了。
- 23: localCharacter = 'a' ; //設定外面定義的localCharacter 變數。
- 24: };
- 25: ++localCounter; //不會影響的block 中的值。
- 26: localCharacter = 'b' ;
- 27: aBlock(); //執行block 的內容。
- 28: //執行完後,localCharachter 會變成'a'
- 29: }
這段例子簡單易懂。
5.對於block語句塊內引用實例變量的計數器+1問題以及處理方法。這個也算是注意點,以及一些冷門面試題會出的問題。
6.因爲受限制於sdk的問題,對於代碼版本中使用新特性block後要對前面系統的支持,可能需要用
NS_BLOCKS_AVAILABLE來做判斷和代碼適配。
7.個人感覺,block做爲代碼或者是編程上一些進階,可能因爲習慣關係還是比較少用到它,甚至我問了一個朋友,居然說,沒怎麼聽說過~
但是作爲代理或是回調的另一種實現方式替代方式,也算是可以慢慢用之然後接受的。