IOS開發-Object-C Block的實現方式
前言:我們可以把Block當作一個閉包函數,它可以訪問外部變數和局部變數,但預設是不可以修改外部變數。你可以使用它來做回調方法,比起使用代理(Delegate)會更加直觀。順帶一提,蘋果很多的介面(API)都使用了Block。 一、Block的基本定義 Block的基本寫法(也是詳細寫法): returnType (^blockName)(params) = ^returnType(params) { // code... };中文再解釋:傳回型別 (^Block的名字)(Block的參數) = ^傳回型別(Block的參數) { 這裡放代碼 },例: int (^myBlock)(int num1, int num2) = ^int(int num1, int num2){ return 100;}; 如果你的Block不需要傳回型別和參數,那麼你可以簡寫為: void (^myBlock2)() = ^(){ };或 void (^myBlock2)(void) = ^void(void){ };傳回型別或參數,沒有的話可以用“void”代替。 你也可以把等號右邊,^後的()刪除,即是: void (^myBlock2)() = ^{ };這樣是不是很簡潔? 你也可以先定義一個Block函數,但不寫函數的實現,我們可以在後面再寫具體函數的實現,像這樣: void (^myBlock2)(void);myBlock2 = ^{ }; 二、Block作為方法定義 把Block定義在方法裡,與上面不同的是,Block的名字不需要在聲明時寫上,而是在後面,像這樣: - (void)getWtihBlock:(void (^)())block{ // code... // 記得要調用block block();} 使用方法: [self getWtihBlock:^{ NSLog(@"sdf");}]; 下面作了一個詳細點的例子,並寫了備忘: /** * 追加自身字串N次(每次複製前加一個換行\n) * * @param string 字串 * @param count 追加次數 * @param stringBlock 目標Block,其中str參數為結果字串 */ // Block也可以定義在方法裡,但是不需要定義Block的名字 // IOS開發很多的API也用到了Block,像UIView的塊動畫- (void)getStrWithString:(NSString *)string CopyCount:(int)count resultString:(void (^)(NSString *str))stringBlock{ NSMutableString *newString = [NSMutableString stringWithString:string]; for (NSUInteger i = 0; i < count; i++) { NSUInteger len = [string length]; NSString *insertString = [NSString stringWithFormat:@"\n%@", string]; [newString insertString:insertString atIndex:len]; } // 調用block,傳入字串newString stringBlock(newString);} 用法也是一樣: BlockObject *block = [[BlockObject alloc] init];[block getStrWithString:@"Garvey" CopyCount:3 resultString:^(NSString *str) { // str為處理後的結果 NSLog(@"str is %@", str); }]; 有時候覆雜的Block文法會令到函數的聲明難以閱讀,所以會經常使用typedef對Block起一個新類型。 typedef void (^ResultBlock)(NSString *str); 定義方法時就變成了: - (void)getStrWithString2:(NSString *)string CopyCount:(int)count resultString:(ResultBlock)stringBlock; 讓我們對比一下,使用typedef前後: // 使用前- (void)getStrWithString:(NSString *)string CopyCount:(int)count resultString:(void (^)(NSString *str))stringBlock; // 使用後- (void)getStrWithString2:(NSString *)string CopyCount:(int)count resultString:(ResultBlock)stringBlock; 注意:使用方法是一樣的,只不過定義變得簡單了。 如果你一直在使用代理(Delegate)進行方法回調,那麼你現在可以嘗試使用Block函數了