ios中的多播委托

1,089 阅读3分钟

1.关于委托

第一次接触多播委托是在C#中,首先关于委托,简单说下,就是标识方法的类,它给方法的签名和返回类型指定名称,可以说是类的提升,它非常类似C++里面的函数指针,但是C#的委托是类型安全的,而C++的函数指针可以将任何一个地址作为函数指向,可以通过定义的委托对象调用方法,在C#中是这样的:

delegate int demoDelegate(int input)

这是一个简单的委托实现,有方法参数,返回值,它可以作为同等方法参数类型和返回值类型的Function,简单实用:

int demoFunc(int input) {
     return input * input
}

上述只是一个简单的函数,使用时只需要初始化委托,并把方法赋值给委托就可以在后面使用了:

myDelegate = new demoDelegate(demoFunc)
int newNumber = myDelegate(10);
//就像是同直接调用方法一样,没什么不同。

2.关于多播委托

那什么是多播委托?有了上面单个委托的基础,在理解多播委托就很好理解了。

namespace DelegateApplication
{
    class MulticastDelegates
    {
        //声明一个委托,委托没有返回值
        public delegate void DemoDelegates(String name);
       //第一个方法
        public static void Hello(String name)
        {
            Console.WriteLine("您好, {0}", name);
        }
 
        public static void GoodBye(String name)
        {
            Console.WriteLine("再见, {0}", name);
        }
 
        public static void Main()
        {
            DemoDelegates delegates = Hello;
            //使用+=给委托添加方法
            delegates += GoodBye;
            String name = "张三李四";
            Console.WriteLine("这是一种方法调用:");
            delegates(name);
            Console.WriteLine("这是另一种方法调用");
            //返回委托的调用列表。
            Delegate[] allDelegates = delegates.GetInvocationList();
            //注意这里的allDelegates列表中存储的是DemoDelegates类型的委托
            foreach (DemoDelegates dele in allDelegates)
            {
                dele(name);
            }
        }
    }
}

运行结果

这是第一种方法调用
你好,张三李四
再见,张三李四
这是另一种方法调用
你好,张三李四
再见,张三李四

。。。。其实就是一个委托数组。。。嗯。多播委托有很多好处,有了多播委托我们就可以同时调用相同类型的方法了。哈哈哈

3.ios中的多播委托

上述的使用都是在C#中实现的,那么在ios中我们可以使用多播委托吗?答案是不能。。。。。但是我们可以自己实现。 最简单的就是声明一个数组,专门用于保存delegate委托,当需要执行时遍历委托数组,并一一执行。 注意:

NSPointerArray* _delegates; //用于存储委托delegate
_delegates = [[NSPointerArray alloc] initWithOptions:NSPointerFunctionsWeakMemory];
//弱引用对象的数组
- (void)addDelegate:(id<Delegate>)observer
{
//添加委托
    @synchronized(_delegates) {
        if (![_delegates containsObject:observer]) {
            [_delegates addObject:observer];
        }
    }
}

- (void)removeDelegate:(id<Delegate>)observer
{
//删除委托
    @synchronized(_delegates) {
        [_delegates removeObject:observer];
    }
}

通过上述操作我们就有了自己的多播委托了,当然同样的服务我们可以使用Notification来实现,实现更方便,但是Notification有很多先天性的缺点:

  1. [NotificationCenter defaultCenter] postNotification],这种方式是同步的,就是消息接收者全部处理完消息之后,post这方才会继续往下执行,因此,尽量不要做太耗时的操作。并且在哪个线程发,就在哪个线程收。 2.再调用addObserver后,结束之后还要调用observer的移除 3.通知发送时,需要查找observer接受通知对象。

在使用多播委托时并不要查找,而是直接遍历调用 通过弱引用对象数组可以保证,当数组中对象被释放后,数组中同时会置为NULL,有助于避免内存leak.

以上就是简单的关于多播委托的理解.