Block

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;
相關文章
相關標籤/搜索