单独创建一个协议文件的意义

对于协议,感觉自己常用的就是 回调传值,再有就是面试的时候可能遇到过面试官提出的这样一个问题,iOS 如何实现多继承?
但是,经常在一些SDK或者第三方碰到一个单独的协议文件,有时候就有些迷糊,这样是干啥呢?就算遵守这个协议,那也没有实现触发方法啥的啊?

单独创建一个协议文件有什么意义呢?

我个人感觉就是用来解耦合的,虽然它单独创建了一个协议文件,但是它归根结底还是协议,只是单独创建出来,便于其他类来使用了而已
segmentfault中我还看到过这样一段解答,感觉说的也非常好

协议是抽象的,只是描述不同事物的一些共性,比如说飞吧, 飞机和鸟都会飞,他们都实现了飞协议,但是他俩的实现方式是不一样的,那么飞这个协议是不是就应该单独定义呢?有一天可能人也会飞了,那么人去实现飞协议就可以了


通过协议提供匿名对象

《编写高质量iOS与OS X代码的52个有效方法》的第28条中是这样来介绍的

  • 用协议把自己所写的api之中的实现细节隐藏起来,将返回的对象设计为遵从此协议的纯id类型
  • 接口背后有多个不同的实现类,而又不想指名具体哪个使用类
例:有三个不同的接口和模型,
  • 班级学生模型 ClassStudentModel
  • 年级学生模型 GradeStudentModel
  • 学校学生模型 SchoolStudentModel

此时需要在个人中心页面中展示学生信息,内容可能来自于任意一个模型,这个时候在页面传递参数用哪个模型都不合适

两种方式解决

  • 1、以前的话自己单独再创建一个模型,将传递的值一一赋值到新模型
  • 2、通过协议提供匿名对象方式
单独创建一个协议文件的意义_第1张图片
普通方式
单独创建一个协议文件的意义_第2张图片
匿名对象方式

文件目录


单独创建一个协议文件的意义_第3张图片
文件目录.jpg

模型类

// 班级类
@interface ClassStudentModel : NSObject 

@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *age;
@property (nonatomic, strong) NSString *sex;

@end

// 年级类
@interface GradeStudentModel : NSObject 

@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *age;
@property (nonatomic, strong) NSString *sex;

@end

// 学校类
@interface SchoolStudentModel : NSObject 

@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *age;
@property (nonatomic, strong) NSString *sex;

@end

协议文件(注意,方法中的名称需要与模型名一致)

@protocol PersonDelegate 

- (NSString *)name;
- (NSString *)age;
- (NSString *)sex;

@end

传值

- (void)presenViewController {
    ClassStudentModel *classModel = [[ClassStudentModel alloc] init];
    classModel.name = @"yanghuixue";
    classModel.age = @"26";
    classModel.sex = @"女";
    
    //    GradeStudentModel *gradeModel = [[GradeStudentModel alloc] init];
    //    gradeModel.name = @"qiangzi";
    //    gradeModel.age = @"25";
    //    gradeModel.sex = @"男";
    
    PersonViewController *personVC = [[PersonViewController alloc] init];
    id  delegate = classModel;
    personVC.delegate = delegate;
    [self presentViewController:personVC animated:YES completion:nil];
}

这里应该着重说一下,参数的类型为 id ,所以任何类型的对象都能充当这一参数,只要其遵循PersonDelegate即可,这也就是在前面图中展示,匿名对象传值方式的优点


展示

@interface PersonViewController : UIViewController

@property (nonatomic, strong) id  delegate;

@end


@implementation PersonViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSLog(@"name = %@", self.delegate.name);
    NSLog(@"age = %@", self.delegate.age);
    NSLog(@"sex = %@", self.delegate.sex);
}

@end

你可能感兴趣的:(单独创建一个协议文件的意义)