1、Block的基本定義函數
Block的基本寫法(也是詳細寫法):動畫
returnType (^blockName)(params) = ^returnType(params) { // code... };
中文再解釋:返回類型 (^Block的名字)(Block的參數) = ^返回類型(Block的參數) { 這裏放代碼 },例:spa
int (^myBlock)(int num1, int num2) = ^int(int num1, int num2){ return 100; };
若是你的Block不須要返回類型和參數,那麼你能夠簡寫爲:code
void (^myBlock2)() = ^(){ };
或orm
void (^myBlock2)(void) = ^void(void){ };
返回類型或參數,沒有的話能夠用「void」代替。blog
你也能夠把等於號右邊,^後的()刪除,便是:ci
void (^myBlock2)() = ^{ };
這樣是否是很簡潔?開發
你也能夠先定義一個Block函數,但不寫函數的實現,咱們能夠在後面再寫具體函數的實現,像這樣:字符串
void (^myBlock2)(void); myBlock2 = ^{ };
2、Block做爲方法定義get
把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;
注意:使用方法是同樣的,只不過定義變得簡單了。
Block基礎部分
1.Block的聲明
Block的定義和函數的聲明差很少,就是把函數名改爲(^blockName)便可。下面是block聲明的代碼。
有返回值的
1
|
int
(^sumBlock) (
int
,
int
);
|
無返回值的
1
|
void
(^myBlock)(
int
,
int
);
|
2.給block塊賦值
給聲明好的block,賦值。block的值就是個函數體,給block塊賦值有兩種方式,一個在聲明的時候賦值,一個是先聲明在賦值。
先聲明再賦值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
//代碼塊的聲明
void
(^myBlock)(
int
,
int
);
//給代碼塊賦值
myBlock = ^(
int
a,
int
b)
{
//test ++; //報錯
NSLog(@
"main_test = %d"
, test);
//blockVar++不報錯;
blockVar ++;
NSLog(@
"blockVar = %d"
, blockVar);
int
sum = a + b;
NSLog(@
"a + b = %d"
, sum);
};
|
在聲明的時候賦值
1
2
3
4
5
|
int
(^sumBlock) (
int
,
int
) = ^(
int
a,
int
b)
{
int
sum = a + b;
return
sum;
};
|
3.調用block
block的使用和普通函數的使用相同,調用方法以下:
1
2
|
//調用代碼塊並接收返回值
int
sum = sumBlock(20, 30);
|
4.把block當作參數傳入函數
1
2
3
4
5
6
|
//把代碼塊做爲函數參數
void
blockFunction(
int
(^myBlock)(
int
,
int
))
{
int
sum = myBlock(10,20);
NSLog(@
"fun_sum = %d"
, sum);
}
|
5.在代碼塊中使用局部變量和全局變量
在block中能夠和對全局變量進行訪問和修改,但對局部變量只能夠訪問,若想修改的話,咱們能夠在聲明局部變量的時候加上關鍵字__block
代碼以下:
1
|
__block
int
blockVar = 0;
|