原文:http://www.cnblogs.com/dagehaoshuang/p/4043264.html

在IOS中为了实现回调一般有如下几个方法:

  1. delegate
  2. 通知中心
  3. block
  4. KVO(较特殊的回调,姑且也算一种)

以上四种中在我自己的项目中比较常用的就是delegate和block了。

在现实中回调的需求也分两种

  1. 一对一的回调。
  2. 一对多的回调。

对于一对一的回调,在IOS中使用delegate、block都能实现。而一对多的回调基本就是通知中心了。

假如现在有一个需求,我们以图片下载为例。这里先忽略哪些SDWebimage等已经封装好的第三方类库。对于图片下载一般的过程如下:

  1. 先判断该图片url是否已经下载完毕。如果已经下载完毕那么直接回调显示图片。如果没有下载那么进入下载过程.
  2. 使用合适的图片下载器下载图片。
  3. 图片下载完毕后回调显示图片。并且把该图片存到缓存中。

这里的难点是回调。如果一个页面中有多个地方需要显示同一张图片,那么势必会发生这样一种情况,就是同时有多个请求下载同意url的图片,并且下载完成后需要同时在多个地方显示图片。要是实现这样的需求,用现有的方案貌似很难解决。有的同学会想到通知中心,但是通知中心其实是一个广播服务,只要注册了接受该通知那么所有的注册者都能收到通知,但事实上我只需要在我需要下载的那个url的图片下载完后给出通知,而不需要所有的下载完毕事件都通知。这时候我们就需要多播委托了。

什么是多播委托?我直接拿其他博客上的一个定义来解释。简单地说,多播委托是指允许创建方法的调用列表或者链表的能力。当多播委托被调用时,列表中的方法均自动执行

在IOS中我就以我们平常用的最多的delagate为例,普通的delegate只能是一对一的回调,无法做到一对多的回调。而多播委托正式对delegate的一种扩展和延伸,多了一个注册和取消注册的过程,任何需要回调的对象都必须先注册。

如何在IOS中实现多播委托?老外早就已经写好了,而且相当的好用。我最初接触IOS多播委托是我在研究XMPPframework的时候,而多播委托可以说是XMPPframework架构的核心之一。具体的类名就是GCDMulticastDelegate,从名字就可以看出,这是一个支持多线程的多播委托。那为什么要支持多线程呢?我的理解是多个回调有可能不是在同一个线程的,比如我注册回调的时候是在后台线程,但是你回调的时候却在UI线程,那就有可能出问题了。因此必须保证你注册的时候在哪个线程上注册的,那么回调的时候必须还是在那个线程上回调的。

下面我讲解写多播委托在IOS中的用法。

我先举个例子,比如有一个UserInfo(有一个userName的属性)的类,页面上有三个lable和一个按钮,当点击按钮的时候给userInfo的userName属性赋值,这时候三个lable同时显示userInfo的userName属性的值。

针对以上过程,我们需要对每个lable向userInfo实例注册,也就是向多播委托注册。当对userInfo的userName赋值的时候调用多播委托的方法,这里也就是调用setText方法。这样就能实现上面的需求了。

用代码表示就是:

//继承自多播委托基类的userInfo类
@interface UserInfo : MulticastDelegateBaseObject
@property (nonatomic,strong)NSString *userName;
@end @implementation UserInfo
-(void)setUserName:(NSString *)userName{
_userName=userName;
[multicastDelegate setText:userName];//调用多播委托
}
@end
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//初始化一个userinfo的实例
userInfo=[[UserInfo alloc] init]; //添加一个lable
UILabel *lable =[[UILabel alloc] initWithFrame:CGRectMake(0, 20, 100, 30)];
lable.backgroundColor=[UIColor blueColor];
lable.textColor=[UIColor blackColor];
[userInfo addDelegate:lable delegateQueue:dispatch_get_main_queue()];//向多播委托注册
[self.view addSubview:lable]; lable =[[UILabel alloc] initWithFrame:CGRectMake(0, 60, 100, 30)];
lable.backgroundColor=[UIColor blueColor];
lable.textColor=[UIColor blackColor];
[userInfo addDelegate:lable delegateQueue:dispatch_get_main_queue()];
[self.view addSubview:lable]; lable =[[UILabel alloc] initWithFrame:CGRectMake(0, 100, 100, 30)];
lable.backgroundColor=[UIColor blueColor];
lable.textColor=[UIColor blackColor];
[userInfo addDelegate:lable delegateQueue:dispatch_get_main_queue()];
[self.view addSubview:lable]; //添加一个按钮
UIButton *btn=[[UIButton alloc] initWithFrame:CGRectMake(200, 20, 100, 50)];
[btn setBackgroundColor:[UIColor blueColor]];
[btn setTitle:@"button1" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(btnCLicked:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn]; } -(void)btnCLicked:(UIButton *)btn{
userInfo.userName=@"123456";//给userInfo赋值
}

源代码点击下载

IOS 多播委托(GCDMulticastDelegate)的更多相关文章

  1. ios多播委托

    在现实中回调的需求也分两种 一对一的回调. 一对多的回调. 对于一对一的回调,在IOS中使用delegate.block都能实现.而一对多的回调基本就是通知中心了. 假如现在有一个需求,我们以图片下载 ...

  2. 【C#进阶】多播委托和委托数组像是一回事~

    这个MathOperation类有三静态方法,参数都是double,并且没有返回值,考虑用Action<>() 这种预定义的委托哦 class MathOperations { publi ...

  3. 委托Delegate,多播委托和委托链

    定义一个委托 public delegate void CalculateDelegate(int 32 x,int 32 y); 定义一个委托类型的变量 public static Calculat ...

  4. C# 注销掉事件,解决多播委托链表的问题

    c#的事件是多播委托.当绑定多个事件时,事件会依次触发,清除掉注册的委托链表:方法1  C# Code  12345678910111213141516171819202122232425262728 ...

  5. 【小白学C#】谈谈C#多播委托因异常而终止的解决方案

    一.前言 前几天,马三在与朋友闲聊技术的时候,朋友忽然抛出一个问题,把马三难倒了,本着求知的精神,回来以后马三就查阅了相关资料并做了一些实验,终于把问题搞明白了,因此写下本篇博客记录一下.首先,问题是 ...

  6. C# 委托链(多播委托)

    委托既可以封装一个方法,又可以对同一类型的方法进行封装,它就是多播委托 using System; using System.Collections.Generic; using System.Lin ...

  7. 多播委托和匿名方法再加上Lambda表达式

    多播委托就是好几个方法全都委托给一个委托变量 代码: namespace 委托 { class Program { static void math1() { Console.WriteLine(&q ...

  8. 委托、多播委托(MulticastDelegate)

    委托.多播委托(MulticastDelegate) 多播委托(MulticastDelegate)继承自 Delegate ,表示多路广播委托:即,其调用列表中可以拥有多个元素的委托.实际上,我们自 ...

  9. 委托、Lambda表达式、事件系列04,委托链是怎样形成的, 多播委托, 调用委托链方法,委托链异常处理

    委托是多播委托,我们可以通过"+="把多个方法赋给委托变量,这样就形成了一个委托链.本篇的话题包括:委托链是怎样形成的,如何调用委托链方法,以及委托链异常处理. □ 调用返回类型为 ...

随机推荐

  1. 将双击“root的主文件”弹出的窗口设置为文件浏览器

    1.双击桌面"root的文件夹"图标, 在过去Centos版本之前,每次双击“root主文件夹”都会弹出文件管理窗口: 解决办法:         关闭所有窗口后,重新双击图标: ...

  2. 高效mysql的习惯(程序员版本)

    高效的mysql 一定要有主键 如果没有主键: 数据多次读写后可能更离散,有更多随机I/O MySQL复制环境中,如果选择RBR模式,没有主键的update需要读全表,导致复制延迟 好的主键特点: 没 ...

  3. Don't Be a Subsequence

    问题 F: Don't Be a Subsequence 时间限制: 1 Sec  内存限制: 128 MB提交: 33  解决: 2[提交] [状态] [讨论版] [命题人:] 题目描述 A sub ...

  4. RPD Volume 172 Issue 1-3 December 2016 评论03

    Using Stable Free Radicals to Obtain Unique and Clinically Useful Data In Vivo in Human Subjects Abs ...

  5. Codechef A Game With a Sheet of Paper

    Discription Yuuko and Nagi like to play the following game: Initially they take a checkered sheet of ...

  6. 1.3(Spring MVC学习笔记)数据绑定

    一.数据绑定介绍 用户发送过来的数据,只有传递到服务器端的参数上才会起作用. 比如用户输入的用户名和密码要和后台方法中代表用户名和密码的变量关联起来, 从而才能使用用户传递的数据进行一些操作,这样数据 ...

  7. 手动编译含package的java源程序(包含外部包中定义的类)

    1)定义一个GSM类,如下: 包名是“SRC.GSM”,并且此程序引用了外部jar包.使用javac命令对GSM.java进行编译: GSM.java所在的文件夹如下所示: 切换到这个目录为当前工作目 ...

  8. url参数的获取

    方法 function getQueryString(name) { var reg = new RegExp("(^|&)" + name + "=([^&am ...

  9. ethtool 命令输出的注意点--网卡参数

    http://blog.csdn.net/msdnchina/article/details/70339689

  10. 网络采集软件核心技术剖析系列(4)---使用C#语言如何将html网页转换成pdf(html2pdf)

    一 本系列随笔概览及产生的背景 本系列开篇受到大家的热烈欢迎,这对博主是莫大的鼓励,此为本系列第四篇,希望大家继续支持,为我继续写作提供动力. 自己开发的豆约翰博客备份专家软件工具问世3年多以来,深受 ...