内部监督办公室的代表 - 需要一些澄清

Ful*_*ton 10 delegates ios

我只是真正开始IOS开发,但通过C#开发ASP.net几年.说实话我以前从来没有真正需要理解委托/事件等,我知道我在编写web.forms时使用它们但是很多功能都是由框架在后面处理的,在幕后.

所以现在我正在开发IOS,我不得不试着去理解它们是如何运作的(我在这里假设代理/事件的理论在语言中是相同的,也许我错了).无论如何,IOS中的以下代码行:

 if ([self.delegate respondsToSelector:@selector(startImporting:)])
 {
            [self.delegate startImporting:self];
 }
Run Code Online (Sandbox Code Playgroud)

我是否正确地认为,在伪代码中,它意味着以下内容:

如果调用此方法的方法/类中有一个名为'startImporting'的方法,则在调用类中调用方法'startImporting'.

希望很清楚.如果是这种情况,那么它基本上与在C#中使用静态方法相同,你可以调用类似的东西:

myImportClass.startImporting();
Run Code Online (Sandbox Code Playgroud)

大概不是,或者就是这样做.那么,我是否错过了代表们的全部观点,他们的利益等等?我已经读过他们一遍又一遍的内容,虽然它有意义,但它从不点击,我从来没有(无论如何都是网页形式)真正看到了使用它们的好处.

这变得越来越重要,因为我正在使用.net中的lambda表达式,并且它们与C#中的委托密切相关,所以当我可以开始使用它们时,我更愿意知道委托实际上为什么和有什么好处.

Fab*_*ser 45

Cocoa中的委托模式用于通知(报告进度等)或查询(请求凭据等)另一个对象而不太了解它.

通常,您使用协议来定义将在委托上调用的方法,然后委托需要符合该协议.您还可以添加委托不需要实现的方法(可选).执行此操作时,您必须调用-respondsToSelector :,因为您不知道委托是否要调用特定方法.

一个例子:
你有一个产生某种东西的类,我们称它为Machine该类的工人Worker.需要根据任务调整机器:

Machine *machine = [[Machine alloc] init];
[machine prepareWithParameters:myParameters];
Run Code Online (Sandbox Code Playgroud)

既然我们有机器,我们想要产生大量的Stuff:

[machine produceStuff];
Run Code Online (Sandbox Code Playgroud)

好的,我们已经完成了.但我们怎么知道何时生产了一个单位Stuff?我们可以让我们的工人不断站在我们的机器旁边等待:

while (![machine isFinished]) {
    if ([machine didProduceStuff]) {
        Stuff *stuff = [machine producedStuff];
        [self doSomethingWithStuff:stuff];
    }
    else {
        // Get a very large coffee...
    }
}
Run Code Online (Sandbox Code Playgroud)

如果机器确实自动通知我们,生产一个单位的时间是不是很好Stuff

@protocol MachineDelegate <NSObject>
@optional
    - (void) machine:(Machine *)machine didProduceStuff:(Stuff *)stuff;
@end
Run Code Online (Sandbox Code Playgroud)

让我们添加worker作为代表machine:

Worker *worker;
Machine *machine = [[Machine alloc] init];
[machine prepareWithParameters:myParameters];
[machine setDelegate:worker]; // worker does conform to <MachineDelegate>

[machine produceStuff];
Run Code Online (Sandbox Code Playgroud)

什么时候Machine完成生产,然后它会调用:

if ([[self delegate] respondsToSelector:@selector(machine:didProduceStuff:)])
    [[self delegate] machine:self didProduceStuff:stuff];
Run Code Online (Sandbox Code Playgroud)

然后worker将接收此方法,并可以做一些事情:

- (void) machine:(Machine *)machine didProduceStuff:(Stuff *)stuff {
    [self doSomethingWithStuff:stuff];
    if ([machine isFinished])
        [self shutDownMachine:machine];
Run Code Online (Sandbox Code Playgroud)

}

对于工人来说,这不是更有效,更容易吗?现在,他可以做更有成效的事情,而不是在机器还在生产时站在机器旁边.您现在可以添加更多方法MachineDelegate:

@protocol MachineDelegate <NSObject>
@required
    - (void) machineNeedsMaintenance:(Machine *)machine;
    - (void) machine:(Machine *)machine fatalErrorOccured:(Error *)error;
    - (BOOL) machine:(Machine *)machine shouldContinueAfterProductionError:(Error *)error;
@optional
    - (void) machineDidEnterEcoMode:(Machine *)machine;
    - (void) machine:(Machine *)machine didProduceStuff:(Stuff *)stuff;
@end
Run Code Online (Sandbox Code Playgroud)

代理也可用于更改对象的行为而无需对其进行子类化:

@protocol MachineDelegate <NSObject>
@required
    - (Color *) colorForStuffBeingProducedInMachine:(Machine *)machine;
    - (BOOL) machineShouldGiftWrapStuffWhenDone:(Machine *)machine;
@end
Run Code Online (Sandbox Code Playgroud)

我希望我可以帮助您了解使用委托稍微抽象代码的好处.

  • 惊人的全面答案.谢谢! (2认同)
  • 优秀!看完这个答案后开始理解代表:) (2认同)