1、認識Block
Block封裝了一段代碼,可以在任何時候執行
Block可以作為函數參數或者函數的返回值,而其本身又可以帶輸入參數或返回值,它和傳統的函數指針很類似,但是有區別:block是inline(內聯函數)的,并且默認情況下它對局部變量是只讀的
蘋果官方建議盡量多用block。在多線程、異步任務、集合遍歷、集合排序、動畫轉場用的很多
2、Blocks的定義
1 //Blocks的定義: 2 int (^MySum)(int, int) = ^(int a, int b) { 3 return a+b; 4 }; 5 //定義了一個叫MySum的blocks對象,它帶有兩個int參數,返回int。等式右邊就是blocks的具體實現 6 //Block可以訪問局部變量,但是不能修改。 7 int sum = 10; 8 int (^MyBlock)(int) = ^(int num) { 9 sum++;//編譯報錯 10 return num * sum; 11 }; 12 //如果要修改就要加關鍵字:__block 13 __block int sum = 10;
Block可以訪問局部變量,但是不能修改,若要修改就要加關鍵字:__block(兩個下劃線) 如:
1 __block int c = 15; //__block 有兩個下劃線 2 MySum sum = ^(int a, int b) //聲明了一個block變量 3 { 4 c = 19;//如果外部的變量用了__block關鍵字,就可以在block內部修改這個變量 5 NSLog(@”c is %i”, c); //block可以訪問外面定義的變量 6 };
3、Blocks和函數、指針對比
1 //定義函數指針 2 int (*myFn)(); 3 4 //定義Blocks 5 int (^MyBlocks)(int,int); 6 7 //調用函數指針 8 (*myFn)(10, 20); 9 10 //調用Blocks 11 MyBlocks(10, 20);
Block、函數、指針三種方式實現兩個數相加 下圖:
或者通過typedef(用于定義類型)定義類型后實現兩數相加:
1 void test1() { 2 // 定義了Sum這種Block類型 3 typedef int (^Sum) (int, int); 4 // 定義了sump這種指針類型,這種指針是指向函數的 5 typedef int (*Sump) (int, int); 6 // 定義了一個block變量 7 Sum sum1 = ^(int a, int b) { 8 return a + b; 9 }; 10 int c = sum1(10, 10); 11 NSLog(@"%i", c); 12 // 定義一個指針變量p指向sum函數 13 Sump p = sum; 14 // c = (*p)(9, 8); 15 c = p(9, 8); 16 NSLog(@"%i", c); 17 }
4、Blocks的賦值
1 //在聲明的同時定義變量,然后賦值 2 int (^MySum)(int,int) = ^(int a,int b) { 3 return a + b; 4 }; 5 //也可先用typedef先聲明類型,再定義變量進行賦值 6 typedef int (^MySum)(int,int); 7 MySum sum = ^(int a,int b) { 8 return a + b; 9 };
?