【问题标题】:How does a delegate work in objective-C?委托如何在 Objective-C 中工作?
【发布时间】:2010-11-05 23:00:03
【问题描述】:
  1. 有谁知道我在哪里可以找到关于objective-C 中应用程序委托的内容和工作方式的良好解释/教程?
  2. 这两本书我对delegates 的关注不够,也没有很好地解释它们,让我真正了解它们的力量和功能。

【问题讨论】:

  • 您写的是“应用程序委托”,但我想这个问题并不是专门针对 Cocoa 应用程序的共享 NSApplication 对象的委托?

标签: ios objective-c delegates


【解决方案1】:

如有疑问,请查看docs

基本上,委托是一种允许对象相互交互而不会在它们之间创建强相互依赖关系的方式,因为这会降低应用程序的设计灵活性。他们可以拥有一个向其发送(或委托)消息的委托,而不是对象相互控制,委托执行他们所做的任何事情,以便响应并对该消息采取行动,然后通常将某些内容返回给另一个对象.

委托也是子类化的更好选择。您不必创建自己的自定义类来稍微改变其他对象的行为方式或向它们传递数据,委托允许对象向它们的委托发送消息以便为它们工作,而无需创建子类以进行微小更改的开销其他对象。

当然,委托的主要缺点是可用的委托方法取决于 Apple 工程师预见到的有用以及他们期望人们需要的常见实现,这对您可以实现的目标施加了限制。尽管正如 Quinn Taylor 指出的那样,这是特定于 Cocoa 框架的,因此并不适用于所有情况。

如果委托是子类化的一个选项,那么就接受它,因为它是管理代码和对象之间交互的更简洁的方式。

【讨论】:

  • 谢谢...我在之前的手册页中找不到任何有关代表的信息。猜我是在错误的部分。
  • 您不太可能在手册页中找到有关 Objective-C 的任何内容。 Apple 的在线文档是权威来源,不仅针对可可的细节,还针对概念背景。
  • @Quinn Taylor:是的,改变了它。虽然是的,但我是在上下文中谈论的,但在一般谈论授权时它并不适用。
【解决方案2】:

如上所述,委托不是 iOS 或 Objective-C 的功能,而只是一种编程技术,不需要特定的语言支持。

可以编写一个类(例如,classA),使其 getDatadoSomething 方法不是由它自己实现,而是由一个委托实现(可能是因为classA 不知道数据是什么或它必须做什么)。

为了实现这一点,classA 提供了一个属性,通常称为 delegate,(它只是一个指向实现委托方法的类 - 委托 - 的指针),然后,当它想要调用那些方法,它实际上调用了委托中的方法:

[self.delegate getData];

[self.delegate doSomething];

self.delegate 最初可能设置为self

self.delegate = self;

即classA 实现了它自己版本的这些方法,除非它们被委托。

任何其他类,如果想成为方法的实现者(即成为委托并可能覆盖 classA 的默认实现),将首先将 classA 的委托设置为它自己。因此,如果 classB 想成为这些方法的委托,在 classB 中,我们将:

classA.delegate = self;

所以当 classA 调用这些委托方法时,它实际上是在调用 classB 来实现这些方法,而不知道 classB 的任何信息,甚至不知道它的存在,而 classB 不必继承 classA。

限制是 classB 只能覆盖 classA 想要委托的方法 - 通过子类化,您可以覆盖任何方法。

协议用于通过定义一个必须由委托实现的方法列表来正式化委托过程(委托不提供方法的默认版本,并且该方法必须在某处实现)或者可以由委托人选择性地实现(即委托人有自己的版本,或者该方法是否没有实现无关紧要)。

【讨论】:

  • 这是一个非常精彩的解释。直到现在我一直难以理解classA.delegate = self 部分。谢谢。
  • 不客气。我也很困惑,只是编写使其工作的代码而不理解为什么。然后突然有人用这样的方式解释它,它点击,你真正理解它是如何工作的,它突然看起来很简单。
【解决方案3】:

委托是一种设计模式;没有特殊的语法或语言支持。

委托只是当某些事情发生时另一个对象向其发送消息的对象,因此委托可以处理原始对象未设计用于的特定于应用程序的细节。这是一种无需子类化即可自定义行为的方式。

【讨论】:

    【解决方案4】:

    我尝试通过简单的程序来阐述它

    两个类

    学生.h

    #import <Foundation/Foundation.h>
    
    @interface Student : NSObject
    @property (weak) id  delegate;
    - (void) studentInfo;
    @end
    

    学生.m

    #import "Student.h"
    @implementation Student
    - (void) studentInfo
    {
        NSString *teacherName;
        if ([self.delegate respondsToSelector:@selector(teacherName)]) {
            teacherName = [self.delegate performSelector:@selector(teacherName)];
        }
        NSLog(@"\n Student name is XYZ\n Teacher name is %@",teacherName);
    }
    @end
    

    老师.h

    #import <Foundation/Foundation.h>
    #import "Student.h>
    
    @interface Teacher: NSObject
    @property (strong,nonatomic) Student *student;
    - (NSString *) teacherName;
    - (id) initWithStudent:(Student *)student;
    @end
    

    老师.m

    #import "Teacher.h"
    
    @implementation Teacher
    
    - (NSString *) teacherName
    {
        return @"ABC";
    }
    - (id) initWithStudent:(Student *)student
    {
        self = [ super init];
        if (self) {
            self.student = student;
            self.student.delegate = self;
        }
        return self;
    }
    @end
    

    main.m

    #import <Foundation/Foundation.h>
    #import "Teacher.h"
    int main ( int argc, const char* argv[])
    {
        @autoreleasepool {
    
            Student *student = [[Student alloc] init];
            Teacher *teacher = [[Teacher alloc] initWithStudent:student];
    
            [student studentInfo];
    
        }
        return 0;
    }
    

    解释 :::

    1. initWithStudent:student 将执行时从 main 方法开始

      1.1 教师对象的属性“学生”将被分配学生对象。

      1.2 self.student.delegate = self 表示学生对象的委托将指向教师对象

    2. 调用 [student studentInfo] 时的 main 方法

      2.1 [self.delegate respondToSelector:@selector(teacherName)] 这里已经委托 指向教师对象,因此它可以调用 'teacherName' 实例方法。

      2.2 所以 [self.delegate performSelector:@selector(teacherName)] 将轻松执行。

    看起来教师对象将委托分配给学生对象以调用它自己的方法。

    这是一个相对的想法,我们看到学生对象称为“teacherName”方法,但它基本上是由教师对象本身完成的。

    【讨论】:

    • Student.m 和 Teacher.h 是相同的。你有机会把正确的代码放上去吗?我正在尝试弄清楚如何使用自定义委托类,但似乎找不到任何有用的示例。你的是迄今为止我见过的最好的。
    • @CamHart 感谢您告知我的错误。如果您在“委托”方面遇到任何其他问题,请在此处发表评论。
    【解决方案5】:

    想象一下,您通过电话打了个电话,然后点了一份披萨。 然后,一个披萨送货员到你家(这是一个代表),当 你付钱买披萨,送披萨的男孩把钱还给他的餐厅。

    你 = 对象送货员 = 代表餐厅 = 对象

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-12
      相关资源
      最近更新 更多