iOS 实现多代理的方法及实例代码

 更新时间:2016年10月12日 16:58:58   作者:哆啦不能没有AMen  
这篇文章主要介绍了iOS 实现多代理的方法及实例代码的相关资料,需要的朋友可以参考下

iOS实现多代理

什么是多代理

用过环信SDK的同学应该对多代理不陌生了,请看下面代码:

 @method
 @brief 注册一个监听对象到监听列表中
 @discussion 把监听对象添加到监听列表中准备接收相应的事件
 @param delegate 需要注册的监听对象
 @param queue 通知监听对象时的线程
 @result
 */
- (void)addDelegate:(id<EMChatManagerDelegate>)delegate delegateQueue:(dispatch_queue_t)queue;

平时我们写得比较多的代理:

@property (nonatomic,weak) id<EMChatManagerDelegate>delegate;

写了上面属性后系统会默认生成set方法:

- (void)setDelegate:(id<EMChatManagerDelegate>)delegate;

通过对两个接口的比较就不难看出:单代理只能设置一个,而多代理可以设置多个,准确来说应该是多代理可以添加多个

多代理有什么用

有些同学可能会问为什么要用多代理?用通知也能实现多个对象同时监听啊。是的,用监听通知的方式也能达到目的。

举个例子:服务端通过 socket 传来一个红点消息{"type":21,"content":"某某消息"},
现在多个页面都想拿到这个消息来判断自己是否需要显示红点。

用通知实现

监听通知

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onReceiveMsg:) name:@"kNotificationName_OnReceiveRedPointMsg" object:nil];

实现通知方法

- (void)onReceiveRedPointMsg:(NSNotification *)noti {
  NSDictionary *info = noti.userInfo;
  if ([info[@"type"] integerValue] == 21) {
    <#code#>
  }
}

用代理实现

注册代理

[[RedPointManager sharedInstance] addDelegate:<#(id<RedPointManagerDelegate>)#>]

实现代理方法

- (void)redPointManagerDidReceive:(RedPointModel *)redPointModel {
  if (redPointModel.type == 21) {
    <#code#>
  }
}

显然,用代理实现更直观明了。

如何实现多代理

上面提到过setDelegate:(id<EMChatManagerDelegate>)delegate的方式是不可行的,当第二次set的时候第一次设置的代理就不被持有了。只能通过addDelegate:(id<EMChatManagerDelegate>)delegate 这种方式来实现。

是不是有点不淡定了,将代理对象add到数组(或者字典)中,会使对象引用计数+1,导致代理对象不能释放。没错,直接把代理加到数组中是不可行的。但是要持有多个代理对象,又要考虑到释放问题怎么搞。看看平时写的代理属性 @property (nonatomic,weak) id<EMChatManagerDelegate>delegate; 突然想到了用weak修饰不就行了吗。

所以,可以通过桥接来实现对多个代理对象的持有。

这样就好办了,数组持有桥接对象,桥接对象再拥有自己的delegate。

class WeakObjectBridge : NSObject {
  weak var weakObject : AnyObject?
  override init() {
    super.init()
  }
  init(object:AnyObject?) {
    super.init()
    weakObject = object
  }
}

操作代理

func operatDelegate(cb: @escaping (_ delegate:AnyObject?) -> ()){
    for weakObjectBridge in self.delegateBridges {
      DispatchQueue.main.async {
        cb(weakObjectBridge.weakObject)
      }
    }
  }

具体调用

func action() {
    operatDelegate { (delegate) in
      if let myDelegate = delegate as? SomeManagerDelegate {
        myDelegate.callBack()
        myDelegate.callback?(msg: ["msg":"hello world!"])
      }
    }
  }

Demo演示

   Demo下载

点击这里下载demo.

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

相关文章

  • ios触屏事件指南

    ios触屏事件指南

    这篇文章主要给大家总结介绍了2种实现ios触屏事件的方法,简单实用,有需要的小伙伴可以参考下。
    2015-05-05
  • IOS开发 支持https请求以及ssl证书配置详解

    IOS开发 支持https请求以及ssl证书配置详解

    这篇文章主要介绍了IOS开发 支持https请求以及ssl证书配置详解的相关资料,需要的朋友可以参考下
    2017-02-02
  • iOS 使用UITextField自定义搜索框 实现用户输入完之后“实时搜索”功能

    iOS 使用UITextField自定义搜索框 实现用户输入完之后“实时搜索”功能

    这篇文章主要介绍了iOS 使用UITextField自定义搜索框 实现用户输入完之后“实时搜索”功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03
  • iOS实现水平方向瀑布流

    iOS实现水平方向瀑布流

    这篇文章主要为大家详细介绍了iOS实现水平方向瀑布流的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-08-08
  • iOS中视频播放的基本方法总结

    iOS中视频播放的基本方法总结

    这篇文章主要给大家介绍了关于iOS中视频播放的基本方法的相关资料,文中分别介绍了MPMoviePlayerController、MPMoviePlayerViewController、AVPlayer以及AVPlayerViewController四种方法,需要的朋友可以参考下
    2018-07-07
  • iOS开发之使用Storyboard预览UI在不同屏幕上的运行效果

    iOS开发之使用Storyboard预览UI在不同屏幕上的运行效果

    使用Storyboard做开发效率非常高,为了防止在团队中发生冲突,采取的解决办法是负责UI开发的同事最好每人维护一个Storyboard, 公用的组件使用轻量级的xib或者纯代码来实现,下面小编就给大家介绍如何使用Storyboard预览UI在不同屏幕上的运行效果,需要的朋友可以参考下
    2015-08-08
  • iOS实现日历翻页动画

    iOS实现日历翻页动画

    本文的内容主要是在IOS中实现日历翻页的动画,界面简单但效果很好,以后可以运用到app中,下面一起来看看。
    2016-08-08
  • iOS 组件化初步构思

    iOS 组件化初步构思

    这篇文章主要介绍了iOS组件化初步构思,并对iOS组件化常用方式的讨论进行了方案分析,以便帮助大家对ios组件化有一个深刻的了解
    2023-03-03
  • iOS新版微信底部返回横条问题的解决

    iOS新版微信底部返回横条问题的解决

    这篇文章主要介绍了iOS新版微信底部返回横条问题的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • 详解ios中scrollView上使用masonry

    详解ios中scrollView上使用masonry

    本篇文章主要给大家详细分析了ios开发中scrollView上使用masonry的详细知识内容,需要的朋友参考下吧。
    2018-02-02

最新评论