block的基本使用
1 // 有參有返回值 2 /* 3 格式: 4 返回值類型 (^變量名)(參數類型及個數) = ^(形參列表){ 5 6 代碼塊語句; 7 8 return ; 9 10 };11 12 */13 // 定義一個有參數/有返回值的block14 int (^myblock1)(int ,int) = ^(int x,int y){15 16 return x+y;17 18 };19 20 int sum = myblock1(10,20);21 NSLog(@"sum = %d",sum);22 23 // 給變量重新賦值24 myblock1 =^(int x,int y){25 26 return x*y;27 28 };29 30 // 使用block,接收返回值31 sum = myblock1(10,20);32 NSLog(@"sum = %d",sum);33 34 // 有參無返回值35 36 /*37 格式:38 void (^變量名)(參數類型及個數) = ^(形參列表){39 40 代碼塊語句;41 42 };43 44 */45 // 定義一個變量myblock2 同時進行賦值46 void (^myblock2)(int ,int )=^(int a,int b){47 48 NSLog(@"a + b = %d",a+b);49 50 };51 52 myblock2(34,12);53 54 // 先定義變量,再賦值55 myblock2 = ^(int x,int y){56 57 int m = x>y?x:y;58 NSLog(@"max = %d",m);59 60 };61 myblock2(34,12);62 63 // 無參無返回值 block64 65 /*66 //定義一個沒有參數/沒有返回值的block變量,并且賦值了67 void (^block變量名)() = ^(){68 69 代碼塊的語句;70 };71 72 優化:73 void (^block變量名)() = ^{74 75 代碼塊的語句;76 };77 78 //block變量的使用79 block變量名();80 81 */82 83 void (^myBlock4)()=^{84 85 NSLog(@"xxxx");86 PRintf("xxxxxx");87 88 };89 90 //使用block變量91 myBlock4();
block的typedef
typedef int (^myBlock)(int,int); myBlock a = ^(int x, int y){ return x + y; }; int c = a(1,2);
block訪問外部變量
1 int main(int argc, const char * argv[]) { 2 @autoreleasepool { 3 int m = 10; 4 5 NSLog(@"1:m = %d",m); // 10 6 NSLog(@"2:m addr = %p",&m); // 棧區 7 // NSString *str = @"abc"; 8 // NSLog(@"str = %p",str); 9 10 // 定義變量,并且賦值11 // 當定義block的時候,block會把外部變量以const的方式復制一份12 // 存放到block的所在的內存中13 void (^myBlock)()=^{14 // m的值不能被修改15 // m = 100;16 17 NSLog(@"5:m addr = %p",&m); // 堆區18 // 可以訪問m的值19 NSLog(@"3:in block m = %d",m); // 1020 21 };22 23 NSLog(@"4:m addr = %p",&m); // 棧區24 // 使用25 myBlock();26 }27 return 0;28 }
打印結果為
// 全局變量存在于數據段int n=0;int main(int argc, const char * argv[]) { @autoreleasepool { __block int m = 10; NSLog(@"1:m add = %p",&m); // 棧區地址 NSLog(@"2:m = %d",m); n = 10; NSLog(@"7:n add = %p",&n); // 數據段 NSLog(@"8:n = %d",n); // 10 // 靜態變量 static int a = 33; NSLog(@"----------%p", &a); // 數據段 // __block 不在以const的方式拷貝 void (^myBlock)()=^{ int x = 100; // 棧區 // m的值可以被修改 m = 100; // 全局變量可以修改 n = 100; // 靜態變量可以修改 a = 10; NSLog(@"4:m addr = %p",&m); // 堆區 // 可以訪問m的值 NSLog(@"3:in block m = %d",m); // 100 NSLog(@"9:n add = %p",&n); // 數據段 NSLog(@"10:n = %d",n); // 100 }; myBlock(); NSLog(@"5:m = %d",m); // 100 NSLog(@"6:m addr = %p",&m); // 堆區 NSLog(@"11:n add = %p",&n); // 數據段 NSLog(@"12:n = %d",n); // 100 } return 0;}
打印結果為
block使用注意
靜態變量 和 全局變量 在加不加 __block都會直接引用變量地址。也就意味著 可以改變修改變量的值,在沒有加__block參數的情況下
全局block:定義在函數外面的block是global(全體的)的 另外如果在函數內部的block,沒有捕獲任何自動變量,那么它也是全局的
棧block:區別為是否引用了外部變量
堆block:是對棧block copy得來。對全局block copy 不會有任何作用,返回的仍然是全局block
block作為函數的返回值
// 定義了一個新的類型 newType2typedef int(^myBlock)(int ,int );myBlock test(){ // 返回block類型 return ^(int a,int b){ return a+b; };}int main() { myBlock n = test(); int a = n(1,2); NSLog(@"a = %d", a); // 3}
block助記符 inlineblock
block 也可以這么定義
// 可以加上形參int (^block)(int x,int y) = ^(int x, int y){ return x + y;};
協議 Protocol
什么是協議?
一些方法的聲明,一般寫到一個.h的頭文件中
方法有兩種: 1) 必須實現 2) 選擇實現
協議的作用:
供其他的類去遵守,如果一個類遵守了一個協議,就應該實現這個協議中定義的必須要實現的方法
協議的寫法
@protocol xxxx <NSObject>// 必須實現的方法(默認)@required// 可選實現的方法@optional@end
遵守協議的步驟: 1) 導入 頭文件 2) 遵守協議 3) 實現方法
protocol類型限制
第一種類型限制:給id類型增加限制
id<xxxxxxx> obj;
增加<xxxxxxx>以后,表示,obj只能賦值遵守了xxxxxxx協議的對象
id<xxxxxxx> obj = d;
第二種類型限制:
表示,obj2賦值的時候,必須是Girl對象,并其遵守 了 xxxxxxx協議.
Girl *mm = [Girl new];
Girl<xxxxxxx> *obj2 = mm;
protocol代理設計模式
請看我之前的博客 >---請點擊這里---<
------------------------------------------------------------------------------------------------------------------------------------------------------------
其他四篇鏈家如下:
新聞熱點
疑難解答