一、block
1> 基本使用
2> block与函数的相同点
3> block对外部变量的访问
4> 用typedef定义block类型与函数类型
定义block类型
① 格式:typedef int (^myBlock)(int, int); ② myBlock是新的block类型的名字 ③ myBlock前的int是block的返回值类型 ④ myBlock后的小括号是形参列表
函数类型
① 格式:typedef int (*fun)(int, int); ② fun是新的函数类型的名字 ③ fun前的int是函数的返回值类型 ④ fun后的小括号是函数的形参列表
5> 示例
/* 1.使用typedef定义分别一个block类型,一个指向函数的指针 2.分别定义一个求和函数,用函数指针指向它 3.用新的block类型定义一个求和的block 4.定义一个输出一条横下的block 5.分别用函数指针和block实现两个数的求和,中间输出一条横线 */ #import <Foundation/Foundation.h> //用typedef定义一个返回值类型为int,有两个int类型形参的block类型 typedef int (^myBlock)(int, int); //用typedef定义一个返回值类型为int,有两个int类型形参的函数指针 typedef int (*sumP)(int, int); //定义一个求和函数 int sum(int a, int b) { return a + b; } int main() { //使用新的block类型定义一个求和的block myBlock sumBlock =^(int a, int b){ return a + b; }; //定义一个输出横线的block void (^lineBLock)() = ^{ NSLog(@"--------------"); }; //使函数指针指向求和函数 sumP p = sum; //通过block输出两个函数的和 NSLog(@"%d", sumBlock(11, 12)); //通过block输出一条横线 lineBLock(); //通过函数指针输出两个数的和 NSLog(@"%d", sumBlock(11, 12)); return 0; }
二、protocol
1> 基本使用
作用
① 声明一个方法列表,不能扩充成员变量 ② 若一个类/协议遵守该协议,就会拥有该协议的方法列表 ③ 可以使用@protocol 提前声明一个协议
定义
① 格式 @protocol MyProtocol < BaseProtocol > 方法列表 @end 1)MyProtocol指定协议的名称 2)BaseProtocol指定该协议遵守的协议,通常遵守的是基协议, 如:NSObject ② @required与@optional 1)@required:默认为该关键字,所定义的方法列表要求遵守该 协议的类在实现文件中必须实现,不实现会发出警告 2)@optional:所定义的方法列表不要求遵守该协议的类实现
2> 协议遵守
类遵守协议
① 格式 @interface Name:NSObject < MyProtocol > @end 1)Name是类名,MyProtocol是协议名 2)Name类将拥有协议MyProtocol声明的所有方法
协议遵守协议
① 格式如协议的定义 1)MyProtocol协议将会拥有BaseProtocol协议中声明的所有方法
3> @property的参数
作用
① 限制成员变量只能接受遵守某种协议的对象
格式
① @property (nonautomic, retain) id< MyProtocol > obj 1)MyProtocol限定obj只能接收遵守MyProtocol协议的对象 2)在相互引用的两个类中,retain参数在另一端要使用assign
4> 协议与分类
协议
① 若为多个不相关的类扩充方法列表,通常使用协议 ② 若父类遵守该协议,则子类也遵守该协议 ③ 若一个协议只被一个类遵守,通常把该协议定义在该类中 ④ 若一个协议被多个类遵守,通常把该协议定义在定义成单独的文件
分类
① 若为单个类或多个相互继承的类扩充方法列表,通常使用分类 ② 若父类用有一个分类,则该类的子类也将拥有该分类 ③ 分类通常定义在单独的文件中
5> 协议的应用
代理模式
① 组成 1)抽象角色:通过接口或抽象类声明真实角色实现的业务方法 2)代理角色:实现抽象角色,是真实角色的代理,通过真实角色 的业务逻辑方法来实现抽象方法,并可以附加自己的操作 3)真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑, 供代理角色调用 ② 实例 1)主人委托保姆照顾孩子 2)老板委托秘书购买机票
协议在代理模式中的应用
① 通常情况下真是角色要定义自己的代理必须实现的规则 ② 协议用来来实现代理所要遵循的规则 ③ 遵循真实角色协议的对象,都可以作为真是角色的代理
6> 示例(多文件)
/******main.m文件******/ #import <Foundation/Foundation.h> #import "Parent.h" #import "Children.h" #import "Nanny.h" int main() { @autoreleasepool { //定义一个Parent对象 Parent *p = [[Parent alloc] init]; //定义一个Children对象 Children *c = [[Children alloc] init]; //定义一个Nanny对象 Nanny *n = [[Nanny alloc] init]; //将对象p的属性Children初始化为c p.children = c; //将对象p的属性nanny初始化为n p.nanny = n; //调用对象p的takeCareTheChildren方法 [p takeCareTheChildren]; } return 0; } /******Parent.h文件******/ #import <Foundation/Foundation.h> // #import "LookAfterTheChildren.h" // #import "Children.h" #import "Nanny.h" @interface Parent : NSObject //声明成员变量nanny,且限定其只能接收遵守LookAfterTheChildren协议的对象 @property (nonatomic, strong) id<LookAfterTheChildren> nanny; //声明成员变量children @property (nonatomic, strong) Children *children; //定义方法,实现照顾children的功能 - (void)takeCareTheChildren; @end /******Parent.m文件******/ #import "Parent.h" @implementation Parent // - (void)takeCareTheChildren { //委托代理nanny来完成照顾children的任务 [_nanny feedTheChildren]; [_nanny playWithTheChildren]; } @end /******Children.h文件******/ #import <Foundation/Foundation.h> @interface Children : NSObject @end /******Children.m文件******/ #import "Children.h" @implementation Children @end /******Nanny.h文件******/ #import <Foundation/Foundation.h> // #import "LookAfterTheChildren.h" //要想成为Parent的代理,必须遵守LookAfterTheChildren协议 @interface Nanny : NSObject<LookAfterTheChildren> @end /******Nanny.m文件******/ #import "Nanny.h" @implementation Nanny //实现LookAfterTheChildren协议的方法,具备照顾children的能力 - (void)feedTheChildren { NSLog(@"喂孩子吃饭"); } - (void)playWithTheChildren { NSLog(@"陪孩子玩耍"); } @end /******LookAfterTheChildren.h文件******/ #import <Foundation/Foundation.h> //由Parent定义的协议,声明照顾children的方法列表 @protocol LookAfterTheChildren <NSObject> //给children喂饭的方法 - (void)feedTheChildren; //陪children玩耍的方法 - (void)playWithTheChildren; @end