block的基本使用
1//有参有返回值2/*3格式:4返回值类型 (^变量名)(参数类型及个数) = ^(形参列表){56代码块语句;78return ;910};1112*/13//定义一个有参数\有返回值的block14int(^myblock1)(int,int) = ^(intx,inty){1516returnx+y;1718};1920intsum = myblock1(10,20);21NSLog(@"sum = %d",sum);2223//给变量重新赋值24myblock1 =^(intx,inty){2526returnx*y;2728};2930//使用block,接收返回值31sum = myblock1(10,20);32NSLog(@"sum = %d",sum);3334//有参无返回值3536/*37格式:38void (^变量名)(参数类型及个数) = ^(形参列表){3940代码块语句;4142};4344*/45//定义一个变量myblock2 同时进行赋值46void(^myblock2)(int,int)=^(inta,intb){4748NSLog(@"a + b = %d",a+b);4950};5152myblock2(34,12);5354//先定义变量,再赋值55myblock2 = ^(intx,inty){5657intm = x>y?x:y;58NSLog(@"max = %d",m);5960};61myblock2(34,12);6263//无参无返回值 block6465/*66//定义一个没有参数\没有返回值的block变量,并且赋值了67void (^block变量名)() = ^(){6869代码块的语句;70};7172优化:73void (^block变量名)() = ^{7475代码块的语句;76};7778//block变量的使用79block变量名();8081*/8283void(^myBlock4)()=^{8485NSLog(@"xxxx");86PRintf("xxxxxx");8788};8990//使用block变量91myBlock4();
block的typedef
typedefint(^myBlock)(int,int);
myBlock a= ^(intx,inty){returnx +y;
};intc = a(1,2);
block访问外部变量
1intmain(intargc,constchar*argv[]) {2@autoreleasepool {3intm =10;45NSLog(@"1:m = %d",m);//106NSLog(@"2:m addr = %p",&m);//栈区7//NSString *str = @"abc";8//NSLog(@"str = %p",str);910//定义变量,并且赋值11//当定义block的时候,block会把外部变量以const的方式复制一份12//存放到block的所在的内存中13void(^myBlock)()=^{14//m的值不能被修改15//m = 100;1617NSLog(@"5:m addr = %p",&m);//堆区18//可以访问m的值19NSLog(@"3:in block m = %d",m);//102021};2223NSLog(@"4:m addr = %p",&m);//栈区24//使用25myBlock();26}27return0;28}
打印结果为
//全局变量存在于数据段intn=0;intmain(intargc,constchar*argv[]) {
@autoreleasepool {
__blockintm =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//静态变量staticinta =33;
NSLog(@"----------%p", &a);//数据段//__block 不在以const的方式拷贝void(^myBlock)()=^{intx =100;//栈区//m的值可以被修改m =100;//全局变量可以修改n =100;//静态变量可以修改a =10;
NSLog(@"4:m addr = %p",&m);//堆区//可以访问m的值NSLog(@"3:in block m = %d",m);//100NSLog(@"9:n add = %p",&n);//数据段NSLog(@"10:n = %d",n);//100};
myBlock();
NSLog(@"5:m = %d",m);//100NSLog(@"6:m addr = %p",&m);//堆区NSLog(@"11:n add = %p",&n);//数据段NSLog(@"12:n = %d",n);//100}return0;
}
打印结果为
block使用注意
静态变量 和 全局变量 在加不加 __block都会直接引用变量地址。也就意味着 可以改变修改变量的值,在没有加__block参数的情况下
全局block:定义在函数外面的block是global(全体的)的 另外如果在函数内部的block,没有捕获任何自动变量,那么它也是全局的
栈block:区别为是否引用了外部变量
堆block:是对栈block copy得来。对全局block copy 不会有任何作用,返回的仍然是全局block
block作为函数的返回值
//定义了一个新的类型 newType2typedefint(^myBlock)(int,int);
myBlock test(){//返回block类型return^(inta,intb){returna+b;
};
}intmain() {
myBlock n=test();inta = n(1,2);
NSLog(@"a = %d", a);//3}
block助记符 inlineblock
block 也可以这么定义
//可以加上形参int(^block)(intx,inty) = ^(intx,inty){returnx +y;
};
协议 Protocol
什么是协议?
一些方法的声明,一般写到一个.h的头文件中
方法有两种: 1) 必须实现 2) 选择实现
协议的作用:
供其他的类去遵守,如果一个类遵守了一个协议,就应该实现这个协议中定义的必须要实现的方法
协议的写法
@protocolxxxx <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代理设计模式
请看我之前的博客 >---请点击这里---<
------------------------------------------------------------------------------------------------------------------------------------------------------------
其他四篇链家如下:
Objective-C知识总结(1)
Objective-C知识总结(2)
Objective-C知识总结(3)
Objective-C知识总结(4)