Objective c 有人能简单地解释一下Objective C代表是如何工作的吗?

Objective c 有人能简单地解释一下Objective C代表是如何工作的吗?,objective-c,delegates,Objective C,Delegates,好吧,这似乎是一个骗人的问题,但如果你耐心听我说,读了整个问题,你就会明白我为什么要问这个问题了 我在网上和这里也看到了很多很好的例子和解释,但我就是搞不懂。对我来说,理解原因和方法很重要,所以不要使用文档中的一些示例(顺便说一句,我在理解苹果文档时真的很差劲,我使用php.net文档,有大量的示例),因为那样我就不懂了 我想要两节课,一节课。它有一个带有花的数组,每个花都是从flowerClass实例化的。因此,flowerClass不知道是什么样的花园实例化了它。有时它只是尖叫着要喝水 所以

好吧,这似乎是一个骗人的问题,但如果你耐心听我说,读了整个问题,你就会明白我为什么要问这个问题了

我在网上和这里也看到了很多很好的例子和解释,但我就是搞不懂。对我来说,理解原因和方法很重要,所以不要使用文档中的一些示例(顺便说一句,我在理解苹果文档时真的很差劲,我使用php.net文档,有大量的示例),因为那样我就不懂了

我想要两节课,一节课。它有一个带有花的数组,每个花都是从flowerClass实例化的。因此,flowerClass不知道是什么样的花园实例化了它。有时它只是尖叫着要喝水

所以,如果这里有人能为我解释一下,我将非常感激

我试过了,根据你们提供的信息,我试过了:

我的花园

#import "Flower.h"

@interface MyGarden : NSObject <WateringDelegate>
{
    Flower *pinkFlower;
}
@end

@protocol WateringDelegate <NSObject>
@required
- (void) giveWaterToFlower;
@end

@interface Flower : NSObject
{
    id <WateringDelegate> delegate;
}

@property (retain) id delegate;
- (void) startToGrow;
@end
我没有进口任何UIKIT或基金会,因为我只是想做一些与代表有关的东西。
那么,这是否正确?

委托是您为应用程序实现自定义行为的地方,它会影响另一个类(例如Cocoa框架中的普通旧对象)的工作方式

在其他不使用委托模式的语言中,您可以对对象进行子类化以更改其行为。Objective-C也允许您这样做,但委托的好处是,您不必每次都要对其进行子类化,一个对象可以是多个其他对象的委托

考虑一个控制器类,它拥有一个带有一些控件的窗口,可能是一个信息表、一个工具栏等。您可以将控制器设置为这些控件的代表,这样当控件需要更多关于它们应该做什么的信息时,它们可以查看控制器。您可能希望自定义窗口的大小调整方式、用户在表视图中选择行时发生的情况、信息的显示方式等等。这些都是控件使用其委托协议中定义的方法对其委托(控制器)进行的调用。如果幸运的话,您可以编写所有自定义代码,而无需将其子类化并拆分为多个文件

另一个好处是,您只需要实现您关心的委托方法。如果默认行为正常,则无需执行任何操作


因此,在您的示例中,flower类将具有某种带有“waterMe”方法的委托协议。委托(可能是garden类,或者其他所有的东西)可以按照您的选择实现它,并且只有在flower类需要时才会调用它。不过值得注意的是,委托在框架中最有用,在框架中,您有一个以通用方式工作的对象,该对象可能被覆盖以完成不同的事情。在您自己的代码中,通常更直接地将自定义行为添加到您自己的对象中,除非您真正打算以通用方式使用它。换句话说,不要试图花时间创建一个可以通用的类,而实际上,您只需要让它以一种特定的方式运行。

委托模式在某些情况下很有用,如Marc所示。问题是,苹果使用它们的时间远远超过了它们应该被使用的时间。特别是,苹果已经尝试(不幸的是,imo)使用委托实现一个基本的事件机制

这与委托模式的目的背道而驰,委托模式将类的行为模块化为组件。事件并不表示行为:它们表示(通常是独立的)依赖于事件发生的动作(即,动作依赖于事件,但效果可能在很大程度上独立于引发事件的对象)

最大的问题是,一个事件只能有一个委托处理程序,而在其他语言中,有许多有效的情况下,我们可能希望一个事件有几个独立的使用者。例如,在C#中,
+=
操作符用于将事件处理程序添加到对象的事件中,从而允许事件的观察者数量不限。不幸的是,Objective-C没有任何内置的事件机制,Apple的核心框架类也没有采用事件模式

至少可以说,在活动中使用代理是有限的。此外,消费者与生产者紧密相连,因为只有一个消费者。因此,另一个消费者不可能(嗯,这是可能的,但这是不明智的)更改生产者的委托

苹果如何将委托用于实际事件的一个例子是
tableView:didSelectRowAtIndexPath
方法。这是一件大事。为什么只允许一件事依赖于所选的行?“解决方案”(虽然这更像是一种变通方法)是让父级使用自己的子级伪事件委托方法公开自己的委托。但这只意味着更多的工作和更多的出错机会

Apple如何正确使用代理模型(就模式而言)的一个示例是
tableView:cellForRowAtIndexPath
方法。此方法允许消费者卸载和定义tableView的行为,并且为其提供多个实现是没有意义的

委托模式的一个优点是它支持组合和继承。也就是说,您可以派生一个控制器类,该类实现自己的委托方法,然后您可以实例化该委托方法,或者您可以简单地使用泛型控件组合类,并自己为该控件提供委托方法

但是,我也不喜欢将当前(父)对象作为
@protocol WateringDelegate <NSObject>
@required
- (void) giveWaterToFlower;
@end

@interface Flower : NSObject
{
    id <WateringDelegate> delegate;
}

@property (retain) id delegate;
- (void) startToGrow;
@end
#import "Flower.h"

@implementation Flower

@synthesize delegate;

- (void) needWater
{
    [[self delegate] giveWaterToFlower];
}

- (void) startToGrow
{
    [NSTimer scheduledTimerWithTimeInterval:10.0 target:self selector:@selector(needWater) userInfo:nil repeats:YES];
}
@end