OC+3-protocol

来源:互联网 发布:带数据统计的二维码 编辑:程序博客网 时间:2024/05/30 23:27
protocol概念及基本使用
1、protocol的基本概念
协议:一些方法的声明,一般写到一个.h的头文件中,供其他的类或者协议去遵守。
在OC中,接口是有一个叫做协议的protocol来实现的。它与java不同的是,它可以声明一些必须实现的方法和选择实现的方法,有选择性的。

2、protocol的使用流程
协议的使用流程:定义协议》再类中采用指定的协议》实现协议中对应的方法(选择性的)
1)定义协议
          @protocol 协议名称 <NSObject>   //默认遵守NSObject协议
             //方法声明列表
          @end
2)采用协议
         1、类遵守协议
               创建类的时候遵守某个或者几个协议
               @interface 类名 :父类<协议名称>
               @end
               
               @interface 类名 :父类<协议名称1,协议名称2>
               @end
           2、协议遵守协议
               某个协议也遵守某个或者某些协议,一个协议可以遵守其他多个协议,多个协议之间用逗号','隔开
                @protocol 协议名称<其他协议名称>
                @end
3)实现对应的方法(必须要实现的)
结论:当我们遵守了某个协议后,就相当于这个类有了协议中所有的方法声明

protocol的其他用法
1、protocol的使用注意
      1)protocol:就一个用途,用来声明一大堆的方法(不能声明成员变量),不能写实现
     2)只要某个类遵守了这个协议,就拥有了这个协议的所有方法声明
     3)只要父类遵守某个协议,那么子类也遵守
     4)protocol声明的方法可以让任何类去实现,protocol就是协议
     5)OC不能继承多个类(单继承),但是可以遵守多个协议。继承(:),遵守协议(<>)
     6)基协议:<NSObject>是基协议,是最根本最基本的协议,其中声明了很多最基本的方法
     7)协议可以遵守协议,一个协议遵守了另一个协议,就可以拥有另一个协议中的方法声明

2、protocol基协议介绍
     NSObject是一个积累,最根本最基本的类,任何其他类最终都要继承它。它还有名字也叫NSObject的协议
     ,它是一个基协议,最根本最基本的协议。
     建议每个新的协议都要遵守NSObject协议。

protocol中@required和@optional
@required@optional是协议方法声明中的两个关键字
它们主要用于控制方法是否要实现(默认是@required),在大多数情况下,用途在于程序员之间的交流
//必须要实现,不实现编译器报错
//不加关键字,默认是要实现的
@required
-(
void)run;
-(
void)eat;
//可以实现,也可以不实现
@optional
-(void)fight;

protocol类型限制
1、protocol类型限制
     1)给id类型增加限制
     Girl *mm = [Girl new];
       
//由于id类型可以接受任何类型的对象,要增加类型限制
       
//id<协议名称>,限制obj,只能赋值遵守了household协议的对象
       id<houseHoldProtocol> obj = mm;
     2)给具体对象增加限制
       1、Girl<houseHoldProtocol> *obj = mm;//在遵守协议的前提下,对象还必须是合理地
       2、@property (nonatomic,strong) Dog<suanShuProtocol> *dog;//人拥有会算数的狗,任意的狗就不可以


2、id和instancetype的区别
     1)instancetype只能作为函数或者方法的返回值
     2)id能作为方法或者函数的返回值、参数类型,也能用来定义变量
     3)instancetype对比id的好处:能够精确地限制返回值的具体类型

protocol代理设计模式
代理模式:婴儿和保姆之间有个协议,保姆遵守该协议,于是保姆就需要实现该协议中的条款,从而成为代理人。
错误:linker command failed with exit code 1 (use -v to see invocation)
     1)重复包含头文件
     2)第三方库
1、protocol代理设计模式概念
MVC模式:m-model(模型)  v-view(视图)  c-controller(控制器)
代理模式:传入的对象,代替当前类完成了某个功能。
利用协议实现代理模式的主要思路:
     1)定义一个协议,里面声明代理类需要实现的方法列表
     2)创建一个代理类(比如BaoMu),遵守上面的协议
     3)在需要代理的类(Baby)中,定义一个对象,类型为id,且遵守代理协议的成员变量
     4)在Baby类中调用成员变量_delegate(代理对象)的方法,调用代理类的方法
     5)main.m或其他使用Baby类的文件中,为成员变量赋值

2、protocol代理模式的应用场合
     1)当对象A发生了一些行为,想告诉对象B(让对象B称为对象A的代理对象)通知场合
     2)对象B想监听对象A的一些行为(让对象B称为对象A的代理对象—》监听器场合
     3)当对象A无法处理某些行为的时候,想让对象B帮忙处理(让对象B称为对象A的代理对象自己不想或不能处理
                 
思路实现例子:
1)协议:#import <Foundation/Foundation.h>
@class Baby;

@protocol lookBabyProtocol <NSObject>
//喂婴儿吃饭
-(
void)feedBabyEat:(Baby*)baby;
//哄婴儿睡觉
-(
void)HongBabySleep:(Baby*)baby;
@end

2)代理类:#import <Foundation/Foundation.h>
//保姆想成为婴儿代理人,必须遵守协议
#import "lookBabyProtocol.h"

@interface BaoMu : NSObject<lookBabyProtocol>

@end

#import"BaoMu.h"
#import
"Baby.h"

@implementation BaoMu
//喂婴儿吃饭
-(
void)feedBabyEat:(Baby*)baby {
    baby.
blood += 10;
   
NSLog(@"保姆正在喂婴儿吃东西!体力值现在为%.2f", baby.blood);
}
//哄婴儿睡觉
-(
void)HongBabySleep:(Baby*)baby {
    baby.
sleep += 20;
   
NSLog(@"保姆正在哄婴儿睡觉!睡眠值现在为%.2f", baby.sleep);
}
@end

3)需要代理的类:#import <Foundation/Foundation.h>
@classBaoMu;
#import "lookBabyProtocol.h"

@interface Baby : NSObject
//保姆、体力值、睡眠
@property(nonatomic,strong)BaoMu<lookBabyProtocol> *bm;//此处代理对象一般为_delegate
@property(nonatomic,assign)float blood;
@property (nonatomic,assign)float sleep;
//吃、睡
-(
void)wantEat;
-(
void)wantSleep;
@end

#import"Baby.h"
#import
"BaoMu.h"

@implementation Baby
-(
void)wantEat {
   
NSLog(@"婴儿在哭...");
   
//保姆要喂他吃
    [
self.bmfeedBabyEat:self];
}
-(
void)wantSleep {
   
NSLog(@"婴儿在哭...");
   
//保姆要哄她睡
    [
self.bmHongBabySleep:self];
}
@end

4)赋值:#import <Foundation/Foundation.h>
#import
"BaoMu.h"
#import
"Baby.h"

int main(int argc, const char * argv[]) {
   
@autoreleasepool{
       
       
BaoMu *baomu = [BaoMu new];
       
Baby *baby = [Baby new];
        baby.
bm = baomu;
        baby.
blood = 10;
        baby.
sleep = 10;
       
        [baby
wantEat];
        [baby
wantSleep];
       
    }
   
return 0;
}

引入协议
@protocol 协议名;//类似@class的用法
1、要遵守这个协议的类,用@protocol 告诉编译器这时一个协议
2、在.m文件中,导入协议头文件
3、在main函数中,也要导入协议头文件
0 0
原创粉丝点击