OC进阶(三)
1.block的基本使用
#import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { //1.无参数 无返回值 void(^myBlock)() = ^ { NSLog(@"block"); }; //2.有参无返回值 void(^myBlock2)(int,int) = ^(int a,int y){ NSLog(@"%d",a+y); }; //3.有参数有返回值 int(^myBlock3)(int,int) = ^(int a, int b){ return a+b; }; //block使用 myBlock(); myBlock2(12,14); int c = myBlock3(10,100); NSLog(@"%d",c); } return 0; }
2.block和typedef
#import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { // 定义一个block变量,并且赋值 void (^myBlock)() = ^{ NSLog(@"helloworld"); }; myBlock(); //定义一个别名 // 给 没有返回值 没有参数的block起一个别名 // Block 是一个类型,不在是一个单纯的变量了 typedef void (^Block)(); Block b1; //block类型的变量 b1 =^{ NSLog(@"helloworld"); }; b1(); //定义有参数\有返回值的 block类型 //定义新的别名 //返回值是int 有两个 int类型的参数 typedef int (^NewType1)(int ,int ); NewType1 nt1 = ^(int a,int b){ return a+b; }; //连续定义多个 NewType类型的变量 NewType1 n1,n2,n3; n1 = ^(int x,int y){ return x>y?x:y; }; int s = nt1(12,23); NSLog(@"s = %d",s); } return 0; }
3.block访问外部的值
#import <Foundation/Foundation.h> /** * block内部访问外部值的问题 * block内部不允许修改外部变量值 */ void test(){ int m = 10; NSLog(@"1:m = %d",m); //10 NSLog(@"2:m addr = %p",&m); //栈区 // NSString *str = @"abc"; // NSLog(@"str = %p",str); //定义变量,并且赋值 //当定义block的时候,block会把外部变量以const的方式复制一份 //存放到block的所在的内存中 void (^myBlock)()=^{ //m的值不能被修改 //m = 100; NSLog(@"5:m addr = %p",&m); //堆区 //可以访问m的值 NSLog(@"3:in block m = %d",m); // ? }; NSLog(@"4:m addr = %p",&m); //栈区 //使用 myBlock(); // 1 2 4 5 3 } //int n=0; int main(int argc, const char * argv[]) { @autoreleasepool { __block int m = 10; NSLog(@"1:m add = %p",&m); //栈区地址 //__block 不在以const的方式拷贝 void (^myBlock)()=^{ //m的值不能被修改 m = 100; // n = 10; // int m = 100; NSLog(@"5:m addr = %p",&m); //堆区 //可以访问m的值 NSLog(@"3:in block m = %d",m); // ? }; myBlock(); NSLog(@"6:m = %d",m); // ? NSLog(@"7:m addr = %p",&m); } return 0; }
4.block作为函数的返回值
#import <Foundation/Foundation.h> //返回值是block类型的 //void (^block)(); //定义新的block类型 //1) 使用 typedef 定义一个新的类型 typedef void (^newType)(); //block类型作为函数的返回值 //2) 用新定义的类型作为函数的返回值 newType test(){ //定义block变量 newType w1 = ^{ NSLog(@"xxxxx"); NSLog(@"hello world"); }; return w1; //返回值block } //重新定义了一个新的类型 newType2 typedef int(^newType2)(int ,int ); newType2 test2(){ //返回一个特殊的"值" 这个值是一个有返回值,有两个参数的的代码块 return ^(int a,int b){ return a+b; }; } int main(int argc, const char * argv[]) { @autoreleasepool { //定义block类型的变量 //3) 定义block变量接收 函数返回的结果 newType n1 = test(); //4) 执行block n1(); /* n2 =^(int a,int b){ return a+b; }; */ newType2 n2 = test2(); //调用block int s = n2(23,12); NSLog(@"s = %d",s); } return 0; }
5.block作为方法的参数
#import "Person.h" @implementation Person -(void)test:(BlockType) block{ if (block !=nil) { block(); } } @end
#import <Foundation/Foundation.h> #import "Person.h" int main(int argc, const char * argv[]) { @autoreleasepool { Person *p = [Person new]; [p test:^{ NSLog(@"xxxxx"); }]; } return 0; }
6.协议
/* 1 - 什么是协议? 一些方法的声明,一般写到一个.h的头文件中 方法有两种: 1) 必须实现 2) 选择实现 2 - 协议的作用: 供其他的类去遵守, 如果一个类遵守了一个协议,就应该实现这个协议中定义的必须要实现的方法 3 - 如何定义一个协议: @protocol xxx <NSObject> 默认情况下遵守 NSObject协议 @end 4 - 类遵守协议的格式: 1) 遵守一个协议: 先导入头文件 @interface 类名 :NSObject <xxx> @end 2) 遵守多个协议 @interface 类名 :NSObject <xxx,aaa,bbb> @end */
7.@required 和 @optional
@protocol baseProtocol <NSObject> //@required 和 @optional 都是协议中的关键字 //@required 修饰的方法是必须要实现的 @required //默认情况下都是必须要实现的 -(void)run; -(void)eat; //@optional 修饰的方法是可以实现,也可以不实现的 @optional -(void)dajia; @end
8.protocol的类型限制
int main(int argc, const char * argv[]) { @autoreleasepool { Dog *d = [Dog new]; Girl *mm = [Girl new]; NSString *str =@""; //增加类型限制 // 第一种类型限制:给id类型增加限制 // id<houseHold> obj; //增加<houseHold>以后,表示,obj只能赋值遵守了houseHold协议的对象 //id<houseHold> obj = d; // 第二种类型限制: //表示,obj2赋值的时候,必须是Girl对象,并其遵守 了 houseHold协议. Girl<houseHold> *obj2 = mm; // 第三种类型限制 obj2.dog = d; } return 0; }
@interface Girl : NSObject<houseHold> //女孩养一条狗, //要求这个狗,必须会算数 @property (nonatomic,strong) Dog<caculatorProtocol> *dog; @end
9.代理模式
#import <Foundation/Foundation.h> @class Baby; @protocol lookBabyProtocol <NSObject> //喂婴儿吃饭 -(void)feedBabyEat:(Baby *)baby; //哄婴儿睡觉:(Baby *)baby -(void)HongBabySleep:(Baby *)baby; @end
#import <Foundation/Foundation.h> @class BaoMu; #import "lookBabyProtocol.h" @interface Baby : NSObject @property (nonatomic,assign) float blood; @property (nonatomic,assign) float sleep; //保姆、体力值、睡眠值 @property (nonatomic,strong) BaoMu<lookBabyProtocol> *bm; -(void)wantEat; -(void)wantSleep; @end
#import "Baby.h" #import "BaoMu.h" @implementation Baby -(void)wantEat{ NSLog(@"婴儿在哭..."); //保姆要喂它吃 [self.bm feedBabyEat:self]; } -(void)wantSleep{ NSLog(@"婴儿在哭..."); //保姆哄婴儿睡觉 [self.bm HongBabySleep:self]; } @end
#import <Foundation/Foundation.h> //保姆想成为baby的代理人,就必须遵守lookBabyProtocol协议 #import "lookBabyProtocol.h" @interface BaoMu : NSObject<lookBabyProtocol> @end
@implementation BaoMu //喂婴儿吃饭 -(void)feedBabyEat:(Baby *)baby{ baby.blood += 20; NSLog(@"保姆正在喂婴儿吃东西,baby.blood = %.2f",baby.blood); } //哄婴儿睡觉 -(void)HongBabySleep:(Baby *)baby{ baby.sleep += 10; NSLog(@"保姆正在哄婴儿睡觉,baby.sleep = %.2f",baby.sleep); } @end