我只是真正开始IOS开发,但通过C#开发ASP.net几年。说实话我以前从来没有真正需要理解委托/事件等,我知道我在编写web.forms时使用它们但是很多功能都是由框架在后面处理的,在幕后
所以现在我正在开发IOS我不得不尝试理解它们的功能(我在这里假设代理/事件的理论在语言中是相同的,也许我错了)。无论如何,IOS中的以下代码行:
if ([self.delegate respondsToSelector:@selector(startImporting:)])
{
[self.delegate startImporting:self];
}
我是否正确地认为,在伪代码中,它意味着以下内容:
如果调用此方法的方法/类中有一个名为'startImporting'的方法,则在调用类中调用方法'startImporting'。
希望很清楚。如果是这种情况,那么它基本上与在C#中使用静态方法相同,你可以调用类似的东西:
myImportClass.startImporting();
可能不是,或者就是这样做。那么,我是否错过了代表们的全部观点,他们的利益等等?我已经一遍又一遍地阅读了它们的内容,虽然它有意义但它永远不会点击,我从来没有(无论如何都是网页形式)真正看到了使用它们的好处。
随着我在.net中使用lambda表达式并且它们与C#中的委托密切相关,这变得越来越重要,所以当我可以开始使用它们时,我更愿意知道为什么以及代表实际上有什么好处是
答案 0 :(得分:45)
Cocoa中的委托模式用于通知(报告进度等)或查询(请求凭据等)另一个对象而不太了解它。
通常,您使用协议来定义将在委托上调用的方法,然后委托需要符合该协议。您还可以添加委托不需要实现的方法(可选)。执行此操作时,您必须调用-respondsToSelector :,因为您不知道委托是否需要调用特定方法。
一个例子:
你有一个产生某种东西的类,我们称之为Machine
和类Worker
的工人。需要根据任务调整机器:
Machine *machine = [[Machine alloc] init];
[machine prepareWithParameters:myParameters];
现在我们有了这台机器,我们想要产生大量的Stuff
:
[machine produceStuff];
好的,我们已经完成了。但是,我们如何知道Stuff
的单位何时生成?我们可以让我们的工人经常站在我们的机器旁边等待:
while (![machine isFinished]) {
if ([machine didProduceStuff]) {
Stuff *stuff = [machine producedStuff];
[self doSomethingWithStuff:stuff];
}
else {
// Get a very large coffee...
}
}
如果机器确实自动通知了我们,生成单位Stuff
时,它会不会很好?
@protocol MachineDelegate <NSObject>
@optional
- (void) machine:(Machine *)machine didProduceStuff:(Stuff *)stuff;
@end
我们将worker
添加为machine
的代表:
Worker *worker;
Machine *machine = [[Machine alloc] init];
[machine prepareWithParameters:myParameters];
[machine setDelegate:worker]; // worker does conform to <MachineDelegate>
[machine produceStuff];
当Machine
生成某些内容时,它会调用:
if ([[self delegate] respondsToSelector:@selector(machine:didProduceStuff:)])
[[self delegate] machine:self didProduceStuff:stuff];
然后worker
会收到此方法并可以执行某些操作:
- (void) machine:(Machine *)machine didProduceStuff:(Stuff *)stuff {
[self doSomethingWithStuff:stuff];
if ([machine isFinished])
[self shutDownMachine:machine];
}
对工人来说,这不是更有效,更容易吗?现在,他可以做更有成效的事情,而不是在机器还在生产时站在机器旁边。您现在可以向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
代理也可用于更改对象的行为而无需对其进行子类化:
@protocol MachineDelegate <NSObject>
@required
- (Color *) colorForStuffBeingProducedInMachine:(Machine *)machine;
- (BOOL) machineShouldGiftWrapStuffWhenDone:(Machine *)machine;
@end
我希望我能帮助您了解使用委托稍微抽象代码的好处。
答案 1 :(得分:1)
了解MVC模型以及使用协议和通知对于掌握代表的使用和目的至关重要。将它们视为与特定操作相关的不同事件的响应者类型。
Hera是stackOverflow中的一些有用链接:
希望有所帮助
答案 2 :(得分:0)
委托对于从其他类
获取回调非常有用那么为什么要使用委托: 那就是我们在类上调用一个方法......这是正常的...如果我们希望实例化的类让我们回调...那就是代理派上用场的地方......
简单的例子: 您可以使用一个类的方法从站点下载歌曲 一旦课程完成下载,你希望课程让你知道。
//protocol declaration
@protocol DownloadProtocol <NSObject>
-(void)OnFinish;
@end
//SOng download class
@interface songs
@property(Strong,nonatomic) id<DownloadProtcol> delegate;
-(void)Download;
@end
@implementation songs
-(void)Download
{
///the code to download goes here
[self callTheCallingClass];
}
-(void)CallTheCallingClass
{
[self.delegate OnFinish];
}
@end
//
@interface mainclass<DownloadProtocol>
@end
@implementation mainclass
-(void)viewDidload
{
Songs *s=[[SOngs alloc]init];
s.delegate=self;
[s download];
}
-(void)OnFinish
{
NSlog(@"Called");
}
@end
看到代表团是通过目标c中的协议实现的。我想你可以理解它的语法。
在songs类中,我们为该协议创建了一个属性。我们将它保存为ID类型...因为在编译时不知道类型。
在歌曲课上完成下载后我们称之为协议方法...
在主类中,我们首先采用协议语法 类 以上是
我们实例化歌曲类
然后将主类对象(self)分配给歌曲类
然后我们必须通过在协议中添加方法名来在.m中应用协议类
所以从现在开始,只要歌曲类通过委托实例变量调用协议方法....主类上的协议方法采用就会运行
试试这段代码希望它有所帮助...
如果您想了解有关此主题的更多信息,请将其作为委托设计模式
主要的好处是 它促进了松耦合编程...