协议

作者: 夜雨聲煩_ | 来源:发表于2017-08-16 16:03 被阅读0次
声明类的协议

协议就是定义公共接口的地方,只要遵守协议,就等于在头文件中定义了这些方法,只要实现就行了。
所以,你可以定义一个协议,然后定义一个类遵循这个协议,在这个类的.m文件里实现这个协议中的方法。这样不需要在.h中声明,也可以在其他类中调用该类对应协议中的方法。如下:

  • 定义协议
#import <Foundation/Foundation.h>
@class HWWashDevice;
@protocol HWWashDeviceParserProtocol <NSObject>
@required
- (void)hw_ParseWashDevice:(HWWashDevice *)device;
@end
  • 对应方法中实现
@implementation HWDeviceParser
+ (instancetype)defaultParser
{
    HWDeviceParser *parser = [[HWDeviceParser alloc] init];
    return parser;
}
- (void)hw_ParseWashDevice:(HWWashDevice *)device
{
    //解析洗衣机属性
    ...
    ...
    ...
}
  • 对该方法的调用
@interface HWWashDevice ()
@property (strong, nonatomic) id<HWWashDeviceParserProtocol> attributeparser;
@end

- (void)setUp
{
    self.attributeparser = [HWDeviceParser defaultParser];
    ...
}

/**
 *  设备属性状态变化
 *
 *  @param device     设备对象
 *  @param attributes 属性发生变化的集合
 */
- (void)device:(uSDKDevice *)device didUpdateVlaueForAttributes:(NSArray<uSDKDeviceAttribute *> *)attributes
{
    NSLog(@"todo:%@", attributes);
    [super device:device didUpdateVlaueForAttributes:attributes];
   

之所以有这样的设计,是因为要将共同的行为抽象出来:不同的类有不同的作用和特征,这也是面向对象的特点,但是即使千差万别,还是会有某些相似点的,这些相似的地方就可以抽象出来做成协议。
其关系如下图:

协议关系.jpeg

那么我们就可以将各个类的协议统一放在一个协议类里(例如把不同种类的菜都放在做菜协议里),不同的类遵循不同的协议(不同的厨师完成不同的具体菜品),这样在实现功能时我们只需在协议里寻找对应方法(具体菜品),然后找到遵循此协议的类(菜品对应的厨师),就可以实现具体功能,使代码逻辑更加清晰。

在一个完全组件化的项目中,关系如下图。

组件化的协议实现方式.jpeg

组件中只需要开放protocol与service即可,其他的所有内容在内部实现,不做开放。
而公共部分只需要找到需要的protocol,即可实现对应方法。

实例
  • 协议部分
    MSViewModelServicesImpl 遵循 MSViewModelServices 遵循 MSNavigationProtocol
    定义方法若干:

      /// Pushes the corresponding view controller.
      ///
      /// Uses a horizontal slide transition.
      /// Has no effect if the corresponding view controller is already in the stack.
      ///
      /// viewModel - the view model
      /// animated  - use animation or not
      - (void)pushViewModel:(MSViewModel *)viewModel animated:(BOOL)animated;
    
      /// Pops the top view controller in the stack.
      ///
      /// animated - use animation or not
      - (void)popViewModelAnimated:(BOOL)animated;
    
      /// Pops until there's only a single view controller left on the stack.
      ///
      /// animated - use animation or not
      - (void)popToRootViewModelAnimated:(BOOL)animated;
    
      /// Present the corresponding view controller.
      ///
      /// viewModel  - the view model
      /// animated   - use animation or not
      /// completion - the completion handler
      - (void)presentViewModel:(MSViewModel *)viewModel animated:(BOOL)animated completion:(VoidBlock)completion;
    
      /// Dismiss the presented view controller.
      ///
      /// animated   - use animation or not
      /// completion - the completion handler
      - (void)dismissViewModelAnimated:(BOOL)animated completion:(VoidBlock)completion;
    
      /// Reset the corresponding view controller as the root view controller of the application's window.
      ///
      /// viewModel - the view model
      - (void)resetRootViewModel:(MSViewModel *)viewModel;
    
  • 实现部分:
    传统方式遵循该协议,并实现协议对应方法。
    RAC 实现方式如下:

    // 不需要遵循该协议。而是创建时传入该协议使之持有。
    - (instancetype)initWithServices:(id<MSViewModelServices>)services;
    

    初始化时注册代理实现方法。

    - (void)registerNavigationHooks {
      @weakify(self)
      // 使用RAC监测方法调用,当方法调用时运行block内部代码,实际上就是协议方法的具体实现。
      [[(NSObject *)self.services
        rac_signalForSelector:@selector(pushViewModel:animated:)]
       subscribeNext:^(RACTuple *tuple) {
           @strongify(self)
           MSViewController *topViewController = (MSViewController *)[self.navigationControllers.lastObject topViewController];
           if (topViewController.tabBarController) {
               topViewController.snapshot = [topViewController.tabBarController.view snapshotViewAfterScreenUpdates:NO];
           } else {
               topViewController.snapshot = [[self.navigationControllers.lastObject view] snapshotViewAfterScreenUpdates:NO];
           }
           UIViewController *viewController = (UIViewController *)[MSRouter.sharedInstance viewControllerForViewModel:tuple.first];
           [self.navigationControllers.lastObject pushViewController:viewController animated:[tuple.second boolValue]];
       }];
    }
    
  • 调用
    最后 viewModel 中再持有一份这个协议。
    利用如下方式调用:

    [self.viewModel.services pushViewModel:model animated:YES];
    

相关文章

  • git协议

    git支持的协议 local协议 https协议 ssh协议 git协议 github常用的协议

  • Dubbo服务 上传文件解决方案以及Hessian协议

    协议支持Dubbo支持多种协议,如下所示: Dubbo协议 Hessian协议 HTTP协议 RMI协议 WebS...

  • Procotol 和 Delegate

    目录 Procotol 协议的概念 协议的分类 协议的定义 协议的遵循 协议的方法 协议的属性 Delegate ...

  • 计算机网络题目

    几种协议分别属于哪一层传输层协议:TCP协议、UDP协议应用层协议:FTP、HTTP、SMTP网络层协议:IP协议...

  • ARP协议

    地址解析协议ARP 网络层四大协议:ARP协议,IP协议,ICMP协议,IGMP协议。 ARP(Address R...

  • IP数据报格式

    前言 先回顾一下TCP/IP协议栈 网络层的协议有IP协议、ARP协议、ICMP协议和IGMP协议。其中IP协议是...

  • 名词解析

    网络层:IP协议 : 网络协议ICMP协议: Internet互联网控制报文协议 ->IP协议的附属协议 IP...

  • 如何将Git仓库备份到本地

    git常用的传输协议传输协议.png哑协议:哑协议传输进度不可见;智能协议传输可见。传输速度:智能协议比哑协议传输...

  • NSURLSession学习笔记

    �Http协议-超文本传输协议 Http协议是应用层协议,底层要求的传输协议必须是可靠的传输协议,通常是TCP协议...

  • dubbo支持的7种协议 (1)

    支持的协议有哪些。 1、dubbo 协议 (默认) 2、rmi 协议 3、hessian 协议 4、http 协议...

网友评论

      本文标题:协议

      本文链接:https://www.haomeiwen.com/subject/ygiirxtx.html