1.协议 代理模式
两个对象之间如何传递数据
同一时间只完成一件事情
一般把协议写在代理中
接受的类型用id并且服从协议(@property(nonatomic ,assign)id<agentDelegate>delegate
一定要确保对象实现了方法
例如:我需要刷新一个数据,可是我访问不到,而viewcontroller可以,我就发布协议,即写一个代理.
@class Footview;//因为代理写在@interface之前,所以要先声明Footview
@protocol 协议名称FootviewDelegate <NSObject>
@required //必须实现
//刷新数据方法的声明
-(void)FootviewReloaddata:(footview *)footview;//一般以协议名字开头,必须传入自身控件为第一参数;
@end
@interface footview :UIview
@property (nonatomic,weak) id<FootviewDelegate> delegate;
@end
在需要刷新数据的地方:
//先判断代理是否实现 ,若实现了,直接调用
if([self.delegate respondsToSelected(footerviewloaddata:)]){
[self.delegate footViewloaddata:self];
}
在viewcontroller 中 先创建FootView,并服从协议, self.delegate = self,实现具体方法;
1.Protocol:声明方法,不能实现。Protocol里面的方法,可以让任何类实现,只要服从协议。Protocol就是协议。只要遵守了协议就拥有了,协议里 的所有方法声明。
c,协议方法声明中的关键字
1)required 要求实现,若没有实现则警告,不报错
2)Optional不要求实现
2.父类遵守了某个协议,子类也遵守。
3.OC不能继承多个类,但是可以遵守多个协议。继承类(:),遵守协议(<>).
4.协议可以遵守协议,一个协议遵守了另一个协议,就拥有另一个协议的方法声明。
a,协议的定义
@protocol 协议名称 <NSObject>
//方法的声明
@end
b,如何遵守协议
类遵守协议
@protocol 类名:父类名<协议1,协议2>
@end
协议遵守协议
@protocol 协议名字<其他协议名>
@end
d,定义变量时遵守协议的限制
类名<协议名称>*变量名 NSObject<Myprotocol>*obj;
Id<协议名称>变量名 id<Myprotocol>obj1;
e,Property中声明的属性可以遵守协议的限制
@property(nonatomic,strong)类名<协议名称>*属性名;
@Property(nonatomic,strong)id<协议名称>*属性名;
例子:老板让秘书找中介租房,并通过QQ,微信或者电话通知老板结果。
f,协议本身写在.h文件里面,也可以定义在任何地方,当协议只有在这个类遵守时,一般把协议写在类里面,若这个协议需要多个类去实现,就可以外面单独的文件里。
1.中介的代理内容
#import <Foundation/Foundation.h>
@protocol RentHouseDelegate <NSObject>
-(void)useQQ:(NSString *)message;
-(void)usetel:(NSString *)telephone;
-(void)useweChat:(NSString *)weChat;
@end
@interface Agent : NSObject
@property (nonatomic,assign) id <RentHouseDelegate> delegate;
-(void)rentHouse;
@end
实现:
#import "Agent.h"
@implementation Agent
-(void)rentHouse{
if ([self.delegate respondsToSelector:@selector(useQQ:)]) {
[self.delegate useQQ:@"找到房子了"];
}
if ([self.delegate respondsToSelector:@selector(useweChat:)]) {
[self.delegate useweChat:@"微信找到房子了"];
}
if ([self.delegate respondsToSelector:@selector(usetel:)]) {
[self.delegate usetel:@"电话找到房子了"];
}
}
@end
2.秘书类服从代理,调用中介的联系方法。
#import <Foundation/Foundation.h>
#import "Agent.h"
@interface Secretary : NSObject<RentHouseDelegate>
@end
#import "Secretary.h"
@implementation Secretary
-(void)useQQ:(NSString *)message{
NSLog(@"%@",message);
}
-(void)usetel:(NSString *)telephone {
NSLog(@"%@",telephone);
}
-(void)useweChat:(NSString *)weChat{
NSLog(@"%@",weChat);
}
@end
3.老板需求
#import <Foundation/Foundation.h>
@interface Boss : NSObject
-(void)needHouse;
@end
#import "Boss.h"
#import "Agent.h"
#import "Secretary.h"
@implementation Boss
-(void)needHouse{
Agent *xiaowang = [[Agent alloc]init];
Secretary *lisi = [[Secretary alloc]init];
xiaowang.delegate = lisi;
[xiaowang rentHouse];
}
@end
4.main函数调用
#import <Foundation/Foundation.h>
#import "Boss.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Boss *zhangsan = [[Boss alloc]init];
[zhangsan needHouse];
}
return 0;
}
2.Block
block 的标识符^
a,定义block变量
Int (^SumBlock)(int,int)//有参数,返回值为int
定义一个block类型的变量,接收两个参数,做加法运算
int (^Sumblock)(int a,int b) = ^(int a,int b){
return a+b;
};
NSLog(@"%d",Sumblock(1,2));
return 0;
Void (^Myblock)()//无参数,返回值类型为空
定义一个block类型的变量,打印n条线
void(^Myblock)(int)= ^(int n){
for (int i = 0; i< n ; i++) {
NSLog(@"----------");
}
};
Myblock(3);
}
b,Block访问外部变量
Block内部可以访问外部变量,默认情况下,Block内部不能修改外部的局部变量。给局部变量加上__block关键字,则这个局部变量可以在block内部进行修改。
c,利用typedef定义block类型,
Typedef int (^MyBlock)(int ,int);
3.Category 类别
1、什么是类别
在已有类的基础之上无需子类化,直接给类添加一些方法
a.继承与类别的区别
继承不仅可以添加一些方法,还可以添加一些属性
类别只能添加方法
b.在使用的时候继承必须创建一个对象再去调用方法,使用类别里面的方法和原有类的使用方式一致
c,类别不会改变现有类的方法,万一重名,自己写的优先级最高