V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Sunnyyoung
V2EX  ›  程序员

iOS 中的 delegate 和 protocal 一直没弄清楚阿

  •  
  •   Sunnyyoung · 2014-10-24 16:44:36 +08:00 · 4169 次点击
    这是一个创建于 3687 天前的主题,其中的信息可能已经有所发展或是发生改变。
    一些人说delegate是通过protocal来实现,又有一些人说delegate跟protocal没有关系,最后搞得不明不白,一头雾水..= =
    有大神来讲解下吗?
    20 条回复    2014-10-25 12:44:51 +08:00
    Heavytiger
        1
    Heavytiger  
       2014-10-24 17:27:57 +08:00
    delegate就是protocol
    Heavytiger
        2
    Heavytiger  
       2014-10-24 17:28:17 +08:00
    说实话我也没搞清。
    LINAICAI
        3
    LINAICAI  
       2014-10-24 17:32:30 +08:00
    协议不过是预先声明的接口,代理是一种设计模式,这个设计模式的实现通过协议来完成。。。其实用多了自然明白
    cdfmr
        4
    cdfmr  
       2014-10-24 17:33:52 +08:00
    delegate是一个对象,protocol是一组规范(接口),某个对象要作为另一个对象的delegate,就要满足那个对象定义的protocol。
    fooevr
        5
    fooevr  
       2014-10-24 17:37:36 +08:00
    protocal是协议,用来定义特定的方法,可以通过@required,@optional,@property来申明该协议需要实现哪些属性或方法。
    delegate可以是一个实现了protocol的类的实例,如:
    @protocal Move<NSObject>
    -(void)turnLeft;
    -(void)turnRight;
    @end

    @interface Dog:NSObject
    @property id<Move> delegate;
    // 伪代码
    [delegate turnLeft];
    @end

    @interface Owner:NSObject<Move>
    // 伪代码
    [Dog setDelegate:self];
    -(void)turnLeft;
    -(void)turnRight;
    @end
    protocol Move 定义了移动的方向,Owner实现了move委托,可以接收到Dog的移动方向的通知,Dog的委托属性则是一个Owner的实例。

    如果你愿意,甚至可以在不在Onwer类中实现协议,而实用performSelector的方式直接通过方法名称调用delegate中的方法。
    如:
    @interface Dog:NSObject
    @property id delegate;
    // 伪代码
    [delegate performSelector:@SEL(turnLeft)];
    @end

    @interface Owner:NSObject
    // 伪代码
    [Dog setDelegate:self];
    -(void)turnLeft;
    -(void)turnRight;
    @end
    所以说protocal相对delegate而言,只是语言层面的一种表述delegate结构的方式,对于执行环境来说并不是必须的。
    fooevr
        6
    fooevr  
       2014-10-24 17:40:30 +08:00
    一次写好,有些错误,如@SEL应该是@selector,其他的请自行脑补😄
    Sunnyyoung
        7
    Sunnyyoung  
    OP
       2014-10-24 17:54:33 +08:00
    @fooevr 既然是定义方法,为什么不定义在interface里面,而要分出来呢
    dorentus
        8
    dorentus  
       2014-10-24 17:59:55 +08:00 via iPhone
    protocol 是语言提供的机制。

    delegate 是实现上的概念,和语言没关系。
    hoogle
        9
    hoogle  
       2014-10-24 18:00:02 +08:00
    @Sunnyyoung 定义和实现在不同的 class
    fooevr
        10
    fooevr  
       2014-10-24 18:00:31 +08:00 via iPhone   ❤️ 1
    @Sunnyyoung 这就是“协议”,双方通过协议规定的规范来就可以实现或者触发,你把这个delegate直接定义成强类型的owner当然也可以,不过就有局限性了,如果一个visitor想订阅这个委托怎么办?
    expkzb
        11
    expkzb  
       2014-10-24 18:27:15 +08:00
    多写写就理解了
    jox
        12
    jox  
       2014-10-24 19:08:06 +08:00
    是protocol不是protocal

    lz如果咱俩之间进行通信,是不是必须得遵从一定的“标准”才行?比如考试的时候选择题作弊,这就是一种protocol,选择题的作弊协议要求咱俩必须约定好哪个手势或者动作是A,哪个是B,哪个是C,哪个是D,假设有个选择题作弊协议标准委员会,大概ABCD的手势就是选择题作弊协议里必须实现的四种方法,至于采用选择题作弊协议的人之间用何种方式实现这四个方法委员会是不管的

    考试的时候,咱俩约好我一咳嗽,你就得开始告诉我答案,我一咳嗽是个特殊的事件,这个事件的发生代表着咱俩之间的通信开始,按照约定好的协议传输数据,在这里,你就是我的delegate,我是个草包啥都不懂,我的考卷上的答案是啥是由你来决定的。

    这么说你明白了吗?
    Sunnyyoung
        13
    Sunnyyoung  
    OP
       2014-10-24 19:52:58 +08:00
    @fooevr
    @jox 感谢两位,还有以上各位热心群众
    对protocol和delegate加深理解了~马上去写几个练习例子来压压惊
    Elethom
        14
    Elethom  
       2014-10-24 19:56:21 +08:00
    Delegate (或 data source 等) 是指向遵循一個或多個 protocol 的 object 的 pointer.
    ldehai
        15
    ldehai  
       2014-10-24 23:11:16 +08:00   ❤️ 1
    @Sunnyyoung

    Protocol就是定义接口规范(协议),Delegate(委托)就是声明支持某规范的具体类。
    如果一个类声明了支持某规范,那就要实现该规范定义的方法。方法我定好了,你去给我实现。

    其实Protocol的作用是给类提供了一种注入代码的方式,可以调用未知类的方法。

    比如有个美女,她喜欢别人送花给她。如果别人愿意送花给她,她就有可能跟他有进一步的发展。于是她声明了一个送花的接口。这个美女就是一个Protocol,她有一个送花的接口,至于送什么花没有说。

    有两个SB兴高采烈的说,我要送花,于是这两个SB就声明了要支持这个协议,并且自己实现了送花的接口,他们就是所谓的Delegate。

    美女开口了,呈上花来(调用送花接口),屌丝男送的是菊花,于是就苦逼的自撸去了;土豪送的是999朵玫瑰,抱的美人归。
    LMkillme
        16
    LMkillme  
       2014-10-24 23:16:59 +08:00   ❤️ 1
    代理是一种设计模式。
    协议是一系列方法的集合,是实现代理这种设计模式的一种方法,block也是实现代理的一种方法。
    kinoAndWorld
        17
    kinoAndWorld  
       2014-10-25 01:28:54 +08:00   ❤️ 1
    Protocol就是其他语言比如JAVA,C#的Interface,不准确的说就是一堆方法的声明。
    Delegate本来是一种设计模式,被Objective—C内置或者说规范化了,它的实现借助Protocol(Interface),但你也可以不用Protocol。

    比如你可以,[self.delegate someMethod];
    这个someMethod有没有被某个Protocol所定义,都无关紧要,只不过用Protocol更规范而已。

    貌似说得有点乱,以上只是个人理解(¯□¯)
    husinhu
        18
    husinhu  
       2014-10-25 08:48:37 +08:00 via iPhone
    回调函数而已
    dikensrover
        19
    dikensrover  
       2014-10-25 11:13:40 +08:00
    @jox 精辟
    jsq2627
        20
    jsq2627  
       2014-10-25 12:44:51 +08:00
    我一开始也是十分不解呀,C#的delegate,objc的delegate,一样的名字,完全是两个东西。
    后来有人一指点,objc的protocol/delegate机制类似java的interface,于是很快就懂了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2939 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 15:01 · PVG 23:01 · LAX 07:01 · JFK 10:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.