OC 协议(代理、传值、回调、多继承)

协议的基础语法

  1. 定义
    协议是方法的列表
    协议只有一个.h文件
    @protocal 协议名称 <NSObject>
    //方法声明列表
    @end

  2. 如何遵守协议< >:

#import “protocol.h”
//类遵守协议
@interface 类名: 父类名 <协议名称1,协议2>
@end
//协议遵守协议
@protocol 协议名称 <协议1 ,协议2 >
@end
  1. 协议方法声明的关键字:
    @optional不要求实现
    @required要求实现(默认)没有实现会发出警告
    基协议:NSObject
    只要一个类遵守了另外一个协议,就可以拥有另一个协议的所有方法声明。

  2. 变量限制

  • 定义一个变量时,限制这个变量保存的对象遵守某个协议:
    类名<协议名称> * 变量名;
    id<协议名称> 变量名;
    如果没有遵守对应的协议,编译器会发出警告。
//要求p保存的对象必须是遵守protocol
NSObject<protocol> *p = [ [NSObject alloc] init ];  //右边就会报错,没有遵守protocol协议
//id相当于NSObject *
id<protocol> obj4 = [ [ Person alloc] init] ;
  • @property中声明的属性也可以限制协议类型
    @property (nonatomic, strong) 类名<协议名称> *属性名;
    @property (nonatomic, strong) id<协议名称> 属性名;
  1. 性能优化:
    类的声明.h文件中用到其他类和协议,优先使用@class, @protocol
    实现文件.m中实际用到再用#import导入

  2. 协议位置
    当协议只用在某个类中,直接写在该类的.h头文件中;
    当多个类/协议需要用到该协议,最好写一个专门的.h协议文件。

代理模式

协议可以单独文件定义,也可以定义在委托方的声明文件中(.h)
代理模式:a委托b干活,以需求方a为主体,找代理,协议写在a中,并建立委托关系a.delegate=b

  • 例1
    Boss要委托Worker去buyMac
//  main.m    
#import <Foundation/Foundation.h>  
#import "Boss.h"  
#import "Worker.h"  
  
int main(int argc, const charchar * argv[])  
{  
    @autoreleasepool {  
        //用协议实现代理   
        //协议中定义了方法buyMac  
        //Boss中有个带协议的id型属性delegate,delegate就可以使用buyMac,但不用实现  
        Boss * mars = [[Boss alloc] init];  
        //老王遵从协议,并实现协议中声明的方法buyMac  
        Worker * laowang = [[Worker alloc] init];  
        //把Boss中delegate指向Worker变量  
        mars.delegate = laowang;  
        //相当于: id<BossDelegate> delegate = laowang;  
        [mars delegateBuyMac];  
        // 相当于: [delegate buyMac];  
    }  
    return 0;  
}
//  Boss.h    
#import <Foundation/Foundation.h>  
  
//协议可以声明于委托方的头文件中  
@protocol BossDelegate <NSObject>  
//协议中规定 被委托的方法 买MAC  
- (void)buyMac;  
@end  
  
@interface Boss : NSObject  
//指向代理的指针,若引用(assign)  
@property (assign) id <BossDelegate> delegate;  
  
//委托代理替自己买MAC  
-(void)delegateBuyMac;  
@end  
//  Boss.m  
#import "Boss.h"   
@implementation Boss  
  
//委托代理替自己买MAC  
-(void)delegateBuyMac  
{  
    //代理指针指向worker  
    [self.delegate buyMac];  
    //id指针调用协议上的方法  
}  
@end  
//  Worker.h  
#import <Foundation/Foundation.h>  
#import "Boss.h"  
  
@interface Worker : NSObject <BossDelegate>  
//worker遵从协议,实现了协议上的方法 即买MAC的方法  
  
//- (void)buyMac;  
@end  
//  Worker.m  
#import "Worker.h"  
@implementation Worker  
//采购MAC  
- (void)buyMac  
{  
    NSLog(@"Worker采购了一批MAC!");  
}  
@end  

代理传值

  1. 正向传值:以委托方为主体,制定协议,代理方遵守协议。
  2. 逆向传值:以功能方(代理方)为主体,制定协议,客户(委托方)遵守协议。
  • 正向传值例子(仍然是Boss和Worker)
//main.m
#import <Foundation/Foundation.h>
#import "Worker.h"
#import "Boss.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Boss * mars = [[Boss alloc] init];
        Worker * laowang = [[Worker alloc] init];
        mars.delegate = laowang;
        //传消息委托老王买Mac
        [mars delegateBuyMac:@"帮我去买一个Mac吧"];
        //询问老王结果
        NSLog(@"%@",[mars askResult]);
    }
    return 0;
}
//  Boss.h    
#import <Foundation/Foundation.h>  
  
//协议可以声明于委托方的头文件中  
@protocol BossDelegate <NSObject>  
//协议中规定 被委托的方法 买MAC  
- (void)buyMac;  
@end  
  
@interface Boss : NSObject   
@property (assign) id <BossDelegate> delegate;  
  
-(void)delegateBuyMac:(NSString*)message;
-(NSString*)askResult;
@end  
//  Boss.m  
#import "Boss.h"   
@implementation Boss  
  
-(void)delegateBuyMac:message{
    [self.delegate buyMac:message];  
}
-(NSString*)askResult{
    return [self.delegate returnMessage];
}
@end  
//  Worker.h  
#import <Foundation/Foundation.h>  
#import "Boss.h"  
  
@interface Worker : NSObject <BossDelegate>  
//worker遵从协议,实现了协议上的方法 即买MAC的方法  
  
//- (void)buyMac;  
@end  
//  Worker.m  
#import "Worker.h"  
@implementation Worker  
- (void)buyMac:message
{
    NSLog(@"收到老板消息:%@",message);
    NSLog(@"我去看一下MAC现在多少钱");
}
-(NSString*)returnMessage{
    return @"boss!我买好了";
}
@end  

运行结果如下图

屏幕快照 2017-09-29 15.03.29.png
  • 逆向传值例子
    下载处理:FirstViewController委托DownLoad下载东西
//main.m
#import <Foundation/Foundation.h>
#import "FirstViewController.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        NSLog(@"Hello, World!");
        FirstViewController* firstVC = [[FirstViewController alloc]init];
        [firstVC loadFirstView];
        
    }
    return 0;
}
//DownLoad.h
#import <Foundation/Foundation.h>
//在提供功能的类中制定协议
@protocol DownLoadDelegate <NSObject>
-(void)finishLoading:(NSString*)message;
@end

@interface DownLoad : NSObject
@property(weak,nonatomic)id delegate;

-(void)downLoadWithUrl:(NSString*)url;
@end
//DownLoad.m
#import "DownLoad.h"

@implementation DownLoad
-(void)downLoadWithUrl:(NSString*)url{
    NSLog(@"开始下载,地址:%@",url);
    NSString* message=@"这里是下载得到的数据#¥%……&*";
    [self.delegate finishLoading:message];  
}
@end
//  FirstViewController.h

#import <Foundation/Foundation.h>
#import "DownLoad.h"

@interface FirstViewController : NSObject<DownLoadDelegate>

-(void)loadFirstView;
@end
#import "FirstViewController.h"
#import "DownLoad.h"

@implementation FirstViewController
-(void)loadFirstView{
    DownLoad* download = [[DownLoad alloc] init];
    download.delegate=self;//构建委托关系
    //向DownLoad传值!!!
    [download downLoadWithUrl:@"www.baidu.com"];
}
//实现协议中的方法
-(void)finishLoading:(NSString *)message{
//获得DownLoad传的值!!!
    NSLog(@"下载完成:数据内容如下:\n%@",message);
}
@end

回调和多继承

参考http://blog.csdn.net/macro_13/article/details/42005775

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容

  • 苹果官方文档翻译 《Objective-C语言编程》(Programming with Objective-C) ...
    fever105阅读 25,666评论 19 130
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,651评论 18 139
  • 1.OC里用到集合类是什么? 基本类型为:NSArray,NSSet以及NSDictionary 可变类型为:NS...
    轻皱眉头浅忧思阅读 1,371评论 0 3
  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,139评论 30 470
  • 今天最后一天输液 这几天下来 真是感慨万千啊 生病了耽误工作不说 还是自己受罪呀 吃药、输液 感觉好痛苦[抓狂] ...
    相思红豆沙阅读 284评论 0 0