Chinaunix

标题: 傻了, 著名的 ios delegate 居然就是这么个东西? [打印本页]

作者: zylthinking    时间: 2013-01-07 15:53
标题: 傻了, 著名的 ios delegate 居然就是这么个东西?
自: http://www.cnblogs.com/lovekarri/archive/2012/03/04/2379197.html
昨天做了一个demo,用到了简单代理。
delegate是ios编程的一种设计模式。我们可以用这个设计模式来让单继承的objective-c类表现出它父类之外类的特征。昨天这个代理实现如下:



类GifView是继承自UIView的,它加载在RootViewController上来通过一个Timer播放动画。同时,RootViewController需要知道Timer的每次执行。

代码如下。

首先,定义GifView,在其头文件中定义代理EveryFrameDelegate,同时声明方法- (void)DoSomethingEveryFrame;


#import <UIKit/UIKit.h>

@protocol EveryFrameDelegate <NSObject>

- (void)DoSomethingEveryFrame;

@end

@interface GifView : UIView
{
    NSTimer *timer;
    id <EveryFrameDelegate> delegate;
    NSInteger currentIndex;
}

@property (nonatomic, retain) id <EveryFrameDelegate> delegate;

@end

然后,只要在GifView.m中让Timer在每次执行的时候调用delegate来执行DoSomethingEveryFrame,代码如下


- (id)initWithFrameCGRect)frame
{
   
    self = [super initWithFrame:frame];
    if (self)
    {
        timer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selectorselector(play) userInfo:nil repeats:YES];
        [timer fire];
    }
    return self;
}

-(void)play
{
        [delegate DoSomethingEveryFrame];

}

GifView上的工作就完成了。

下面是RootViewController中的代码,RootViewController只要在定义GifView的时候指定其代理为自身,就可以知道Timer的每次执行:


- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    CGRect rect = CGRectMake(0, 0, 200, 200);
    GifView *tmp = [[GifView alloc] initWithFrame:rect];
    tmp.delegate = self;
    [self.view addSubview:tmp];
    [tmp release];
}

- (void)DoSomethingEveryFrame
{
    NSLog(@"I'm the delegate! I'm doing printing!";
}

GifView中Timer每次执行都会打印一行

I'm the delegate! I'm doing printing!

故,RootViewController就知道Timer的每次执行了。


他娘的, 这不就是 java 的所谓 interface, c++ 的抽象类, 或者说的更玄乎些, symbian 大力鼓吹的 listener 模式么?
说白了, 只不过一个约定而已, 说明, 我这个类肯定实现了签名为 xxx 的函数, 然后将对象指针塞给你


作者: captivated    时间: 2013-01-07 16:57

delegate原本就是某些指针被阉割(从而也就木有函数指针)的语言才搞出来的玩意. C/C++本来是不肿木需要用这种模式的, 当然非要抛弃函数指针用这玩意也可以[意思就是要OOP啊OOP].
函数式编程语言中就更不需要这种玩意了.
作者: _Rayx    时间: 2013-01-07 17:00
本来委托就是回调啊。
作者: osmanthusgfy    时间: 2013-01-07 17:09
说专业一点就是observer模式,
本质上其实就是一个接口, 相当于C++的抽象类,java中的interface。

我很讨厌那些发明新语言的人,更讨厌把一个旧的技术用一个看似很高深的术语来唬人的家伙.

当然,这样在一些菜鸟面前可以显得很NB。
作者: hellioncu    时间: 2013-01-07 17:14
都是语法糖
作者: starwing83    时间: 2013-01-07 19:01
本帖最后由 starwing83 于 2013-01-07 19:05 编辑

回复 2# captivated


    顺带说一下,静态类型+无第一类函数语言才需要delegate……(其实这个名儿就是interface/virtual class/xxxx的通俗说法……就比如说我们拿“玉米”叫玉蜀黍。然后C++er们写文章的时候都说“玉蜀黍咋地咋地”,听起来多别扭,然后有一个文学家就说“何必说的这么文绉绉的呢?我们直接说“玉米”吧,大概就是这么个情况,倒不是所谓“生造概念”)

动态类型,或者(还是并且?)有第一类函数的,都是不需要这个机制的。

事实上从C++的情况来看,template+functor就可以完全模拟virtual class了。就是这个原理。

写完了以后发现其实括号里面的才是正片啊……sigh……

再或者一下………………如果我没记错的话,.net的第一个版本出来是05/06左右那个时候吧。

如果说delegate的话,在我印象里面是.net先提出来并且在语言里面直接使用这个词儿了吧……怎么就成了“ios delegate”了呢= =
作者: qinggeng    时间: 2013-01-08 09:33
本帖最后由 qinggeng 于 2013-01-08 09:39 编辑

Observer个屁呀,就是他妈的一个原始得不能再原始的实例+方法的回调函数。比C#的delegate的可扩展性差很多。
只不过在Apple的框架下,这种回调不一定是直接回调,而可能是通过异步的消息队列进行回调。
每用一次我就更加想念c++里的template+functor,或者javascript里面的function。
Apple这种delegate最大的问题就是扩展性太差。一个delegate的Instance必须实现全部的interface,虽然可以用其他一些东西绕过去,但是非常讨厌。
Apple擅长做大玩具,然后给大玩具起个装逼的名字,然后就“being cool”了。
玩具就是他妈的玩具,根本不适合严肃的工作场合。
我这两年写objc是越写越讨厌的。正准备慢慢地把objc从项目里挤压掉只剩下GUI的部分,其余的用c++实现。




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2