有人能简单解释一下Objective C代表的工作方式吗?

问题描述

| 好的,这似乎是一个重复的问题,但是如果您支持我并阅读了整个问题,您就会明白我为什么要提出这个问题。 我在网络上和这里都看到了许多不错的示例和说明,但是我无法理解。对我来说,理解为什么和如何操作很重要,因此与其使用文档中的一些示例(顺便说一句,我确实很了解Apple Docs,Im与PHP.net文档一起使用,还有大量示例),因为那时我只是不明白。 我想要两个课,一个gardenClass。它具有一个包含花的数组,每个花都从flowerClass实例化。因此,flowerClass不知道实例化哪种花园。有时候它只是尖叫着喝水。 因此,如果有人可以为我解释这一点,我将不胜感激! 我尝试了一下,这是我根据你们从我那里得到的信息来试一试: 我的花园
#import \"Flower.h\"

@interface MyGarden : NSObject <WateringDelegate>
{
    Flower *pinkFlower;
}
@end
我的花园
#import \"MyGarden.h\"
#import \"Flower.h\"

@implementation MyGarden

- (void) giveWaterToFlower
{
    NSLog(@\"Watering Flower\");
}

- (void)viewDidLoad
{
    pinkFlower = [[Flower alloc] init];
    [pinkFlower setDelegate:self];
    [pinkFlower startToGrow];
}
@end
花h
@protocol WateringDelegate <NSObject>
@required
- (void) giveWaterToFlower;
@end

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

@property (retain) id delegate;
- (void) startToGrow;
@end
花.m
#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
我尚未导入任何UIKit或基金会,因为我现在尝试在这里进行与委托相关的工作... 那么,这是正确的吗?     

解决方法

委托是您为应用程序实现自定义行为的地方,该行为会影响另一个类(例如Cocoa框架中的普通对象)的工作方式。 在其他不使用委托模式的语言中,您可以将对象子类化以更改其行为。使用Objective-C也可以做到这一点,但是委托的好处在于,您不必每次都要进行细微更改时都可以继承子类,一个对象可以是多个其他对象的委托。 因此,请考虑一个控制器类,该类拥有一个带有一些控件的窗口,也许是一个信息表,一个工具栏等。您可以将控制器设置为这些控件的委托,以便在控件需要有关其功能的更多信息时他们应该去找您的控制器。您可能想要自定义窗口的大小调整方式,用户在表视图中选择一行时发生的情况,信息的显示方式等等。这些都是控件使用其委托协议中定义的方法对其委托(您的控制器)进行的调用。如果幸运的话,您可以编写所有自定义代码,而无需子类化并将其拆分为多个文件。 另一个好处是您只需要实现您关心的委托方法。如果默认行为很好,则无需执行任何操作。 因此,在您的示例中,flower类将具有某种使用“ waterMe \”方法的委托协议。委托(也许是花园类,或其他所有类)可以根据您的选择来实现此目的,并且只有在花类需要时才调用该委托。值得注意的是,委派在框架中最有用,在框架中,您有一个对象以通用方式工作,可能会被覆盖以完成不同的事情。在您自己的代码中,通常可以直接将自定义行为添加到您自己的对象中,除非您确实打算以通用方式使用它。换句话说,不要试图花时间去创建一个可以正常表现的类,而实际上,您只会使它以一种特定的方式表现。     ,如Marc所示,委托模式在某些情况下很有用。问题在于,苹果公司使用它们的时间远远超过了应使用的时间。特别是,Apple尝试(失败的是imo失败了)使用委托来实现基本的事件机制。 这违背了委托模式的目的,该模式将类的行为模块化为组件。事件不代表行为:它们代表(通常是独立的)根据事件发生而发生的动作(即,动作取决于事件,但是效果可能很大程度上独立于引发事件的对象)。 最大的问题是,一个事件只能有一个委托处理程序,而在其他语言中有很多有效的情况,我们可能希望有一个事件的多个独立使用者。例如,在C#中,“ 4”运算符用于将事件处理程序添加到对象的事件中,从而允许事件的观察者数量不受限制。不幸的是,Objective-C没有任何内置的事件机制,Apple的核心框架类也没有采用这种事件模式。 至少可以说使用委托进行事件。此外,由于只有一个消费者,因此消费者与生产者紧密相关。因此,另一个消费者不可能更改生产者的委托(这是可行的,但不是明智的选择)。 Apple如何使用代表进行实际事件的示例是“ 5”方法。那是一件大事。为什么只允许一件事取决于所选择的行? “解决方案”(尽管它更多的是一种解决方法)是让父级使用其子级的伪事件委托方法公开其自身的委托。但这仅意味着更多的工作和更多的出错机会。 Apple如何正确使用委托模型(就模式而言,这尤其如此)的一个示例是“ 6”方法。此方法允许用户卸载和定义tableView的行为,并且提供多个实现是没有意义的。 关于委托模式的一件好事是,它同时支持组合和继承。也就是说,您可以派生一个实现自己的委托方法的控制器类,然后可以实例化该类,或者可以简单地使用通用控件来构成您的类,并自己为该控件提供委托方法。 但是,我也不喜欢将当前(父)对象作为组件(子)对象的代表进行传递,因为这会导致类污染和概念不匹配(整个类现在只为它的组成部分之一,而不是属于类本身的概念)。更好的方法是提供一个特殊的映射对象,该对象实现必要的委托方法。但是,由于这在Objective-C中并不方便,因此不幸的是,前者最常被惯例采用。     ,就目前而言,当花要喝水时,它叫
self.delegate giveWaterToFlower
。 default8ѭ默认设置为
MyGarden
,因此当花要喝水时,
MyGarden
中的
giveWaterToFlower
方法会被调用。如果实现了
wateringCan
对象,则
wateringCan
可以做
[pinkFlower setDelegate:self];
。然后,当花要喝水时,
self.delegate giveWaterToFlower
会在
wateringCan
中调用
giveWaterToFlower
方法,这可能会提供比默认值更多或更少的水。同样,您可以实现一个
gardenHose
对象,该对象还提供了一个
giveWaterToFlower
方法。园艺软管只能与花园保持一定距离,因此只能覆盖特定花朵中的代表。 但是设计模式是
flower
已将其
giveWaterToFlower
方法委托给另一个对象。
flower
对象不知道是谁提供了
giveWaterToFlower
方法。您可以在
flower
中包括默认的
giveWaterToFlower
方法,并用
self.delegate = self;
初始化
flower
对象     

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...