Objective-C知识总结(5)
block的基本使用
1 // 有参有返回值 2 /* 3 格式: 4 返回值类型 (^变量名)(参数类型及个数) = ^(形参列表){ 5 6 代码块语句; 7 8 return ; 9 10 }; 11 12 */ 13 // 定义一个有参数\有返回值的block 14 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 // 无参无返回值 block 64 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); // 10 20 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作为函数的返回值
// 定义了一个新的类型 newType2 typedef 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代理设计模式
请看我之前的博客 >---请点击这里---<
------------------------------------------------------------------------------------------------------------------------------------------------------------
其他四篇链家如下: