美文网首页IOS面试大全
问题:什么是代理模式?

问题:什么是代理模式?

作者: 姜小舟 | 来源:发表于2020-05-09 11:30 被阅读0次

    在iOS中有很多种消息传递方式,首先简单了解一下常见的消息传递的几种方式

    • 通知(notification):在iOS中由通知中心进行消息接收和消息广播,是一种一对多的消息传递方式。(使用后需要移除通知)
    • 代理(delegate):代理模式是一种消息传递方式,一个完整的代理模式包括:委托对象、代理对象和协议。。
    • block:在iOS 4.0中开始引入的一种回调方法,可以将回调处理代码直接写在block代码块中,看起来逻辑清晰代码整齐。
    • target action:通过将对象传递到另一个类中,在另一个类中将该对象当做target的方式,来调用该对象方法,从内存角度来说和代理类似。
    • KVO:NSObject的Category(分类)-NSKeyValueObserving,通过对属性进行监听的方式来监测某个值的变化,当值发生变化时调用KVO的回调方法。

    概述

    代理模式是一种消息传递方式,一个完整的代理模式包括:委托对象、代理对象和协议。

    名词解释

    • 协议:用来指定代理双方可以做什么,必须做什么。
    • 委托对象:根据协议指定代理对象需要完成的事,即调用协议中的方法。
    • 代理对象:根据协议实现委托方需要完成的事,即实现协议中的方法。
      三者之间的关系如下图: 代理三要素之间关系

    Protocol-协议

    从上图中我们可以看到三方之间的关系,在实际应用中通过协议来规定代理双方的行为,协议中的内容一般都是方法列表,当然也可以定义属性,我会在后续文章中顺带讲一下协议中定义属性。

    协议是公共的定义,如果只是某个类使用,我们常做的就是写在某个类中。如果是多个类都是用同一个协议,建议创建一个Protocol文件,在这个文件中定义协议。遵循的协议可以被继承,例如我们常用的UITableView,由于继承自UIScrollView的缘故,所以也将UIScrollViewDelegate继承了过来,我们可以通过代理方法获取UITableView偏移量等状态参数。

    协议只能定义公用的一套接口,类似于一个约束代理双方的作用。但不能提供具体的实现方法,实现方法需要代理对象去实现。协议可以继承其他协议,并且可以继承多个协议,在iOS中对象是不支持多继承的,而协议可以多继承。

    @interface TMGameViewControllerNew ()<ILVLiveAVListener,ILVLiveIMListener,AVAudioPlayerDelegate,TMGameViewModelDelegate,TMGameShowViewProcotol,TMGameControlViewDelegate,QAVChangeDelegate,CAAnimationDelegate,TMMsgTooBarDelegate,UINavigationControllerDelegate>{
        NSInteger _chargeSource;
        BOOL _firstComeRoom;
        BOOL _firstGuideCamera;
    }
    

    委托对象

    if ([self.delegate respondsToSelector:@selector(userLoginWithUsername:password:)]) {
          // 调用代理对象的登录方法,代理对象去实现登录方法
          [self.delegate userLoginWithUsername:self.username.text password:self.password.text];
      }
    

    代理对象

        self.gameView = [[TMGameView alloc]initWithFrame:self.view.frame parentVC:self viewModel:self.gameViewModel];
        self.gameView.avIsLoad = NO;
        self.gameView.showView.delegate = self;
        self.gameView.controlView.delegate = self;
        self.gameView.msgToolBar.delegate = self;
    /**
     *  代理方实现具体登录细节
     */
    - (void)userLoginWithUsername:(NSString *)username password:(NSString *)password {
        NSLog(@"username : %@, password : %@", username, password);
    }
    

    代理属性使用weak

    • 首先:在我们的tableViewController中,控制器的view就是tableView,这就相当于tableViewController强引用着tableView(代理对象)。
    • 然后:当我们设置delegate的时候,一般都是让tableViewController成为代理,这个时候代理如果也使用strong,那么tableView的delegate又强引用着tableViewController,所以导致循环引用,因此代理得用weak!
    • 为什么不用assign
      weak和assign是一种“非拥有关系”的指针,通过这两种修饰符修饰的指针变量,都不会改变被引用对象的引用计数。但是在一个对象被释放后,weak会自动将指针指向nil,而assign则不会。在iOS中,向nil发送消息时不会导致崩溃的,所以assign就会导致野指针的错误unrecognized selector sent to instance。

    相关文章

      网友评论

        本文标题:问题:什么是代理模式?

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