2

我正在尝试自学 Objective-c,但来自 Python/Java 背景,事实证明这非常困难。我试图发布一堆我很困惑的观点,但它被标记为太模糊,所以我将它分成几个部分。

首先,我发现的每个委托和出口示例都使用可可视图代码来传达这个想法。不幸的是,我对代码的理解还不够,无法掌握示例的要点。那么,任何人都可以提供一个更基本的代表示例吗?我的理解是它是一种子类化方式;这比传统的子类化有什么好处?为什么每个 cocoa 项目都会自动包含 appDelegate.m?委托可以用于其他目的,而不仅仅是 GUI 的东西吗?

好吧,我想我明白了。所以委托是一个符合其他类协议的类。协议只是必须(或可以,如果设置为可选)在委托类中实现的方法和变量的列表。要创建委托,您必须使用 @interface 关键字,然后是委托的名称,然后(在 < > 符号中)协议名称?所以如果类 c1 想将自己设置为类 c 的委托,类 c 必须首先指定一个协议,对吗?然后,您将能够在 c1 中实现 c 协议中的所有内容:@interface c1; 我觉得我在那里遗漏了一些东西,但希望我的概念是正确的。:) 这也解释了神秘的小于和大于符号;他们声明委托实现的接口。

插座同样总是与查看代码相关联。它们似乎是某种对象间消息传递系统。是对的吗?同样,一个不与复杂的 GUI 语句混合的基本出口的例子会很棒。所以永远不需要网点?我知道除了与 Interface Builder 一起使用外,不需要 IBOutlet 和 IBAction,但我认为插座比这更通用?文档似乎表明它们甚至不是专门用于接口的,而是可以用于任何东西。

提前感谢您的帮助。

4

5 回答 5

2

更新:代表不必遵守协议。协议只是使要求某些类具有方法变得更加容易。它可以让您确定一个已设置为委托的对象实现了某个方法,因此您可以安全地调用它,并允许编译器验证该方法确实已实现(如果您将委托实例变量声明为id<SomeProtocol> delegate,编译器将如果您尝试设置delegate为不符合的类的对象,则给出警告或错误SomeProtocol

协议有助于确保安全,但并非绝对必要。一个类可以有一个委托(或多个!),它们根本不必遵守任何协议。

至于插座,不,它们是专门用于且仅与 Interface Builder 一起使用的。IBOutletand关键字对IBAction代码没有影响(它们甚至在编译之前就被去掉了)——它们只是 Interface Builder 寻找的标记,因此它知道哪些属性和方法应该在接口中可访问。术语“出口”是对标记为 的东西的直接引用IBOutlet,并且实际上没有用于我可以告诉的任何其他上下文中。

同样,如果您不立即理解这一点也没关系。仔细考虑一下,在某些时候,它会“点击”。追了半天,就这样,有一天,我才发现,代言人真的没有什么特别的。它们是其他对象引用的常规对象——只是这种设计模式有一个特殊的名称(委托),而这些对象仅称为委托。它们可以很容易地被称为gyrosor falafels,并且净效果是一样的。:P
你不需要delegate为它命名一个对象来成为一个委托;这只是一个约定。


关于代表:首先要了解,这让我有一段时间,直到我有正确的“啊哈!” 时刻,“代表”没有什么特别之处。“委托”一词只是另一个类所依赖的一类对象的标题,通常用于内容或决策。当开发人员不想(或不能)通过名称将他们的一个类绑定到另一个类时,他们将使用委托 - 这是一种面向对象的解耦方式并使类更通用。

现在,很多时候,类将要求委托具有它们所依赖的特定方法,而确保这一点的一种方法是使用协议(通常称为 Java 中的接口)。协议定义了一系列方法;类“符合”协议,如果他们在他们的接口中声明他们这样做(例如@interface IFObject : NSObject <SomeProtocol> { ... })并且如果他们实现了他们需要的所有方法。协议也可以有可选的方法。

该模型通常与视图控制器、视图和 GUI 一起使用,因为许多 AppKit 和 UIKit 类被编写为尽可能通用。NSTableView,例如,实现它可能实现的最基本的行为,而不需要任何特定于实现的信息;其余的,它依赖于其他对象,即符合NSTableViewDelegateNSTableViewDataSource协议的对象。任何对象都可以符合协议,只要它们实现了正确的方法(在这种情况下,控制器类通常会实现两种协议的方法,但不必如此)。事实上,更好地理解这个主题的一个简单方法是看一下NSTableView- 它有一个delegate属性和一个dataSource属性,但实际上,它们没有什么不同。delegate可以被调用monkeyButt,并且这个概念仍然有效。关键是不要将代表视为黑匣子——它们没有什么特别之处。

代表也可以用于非 GUI 目的;正如您所提到的,一个具体的例子是应用程序委托。NSApplication发送一个委托通知,让它知道应用程序何时启动(除其他外),因此它可以设置商店。同样,出于任何目的,任何对象都可以成为任何其他对象的委托。这只是一个约定。


简要介绍出口:正如其他人所提到的,出口只是在 XIB 中定义的接口与您的代码之间的连接。它们是让 Xcode 将界面链接到适当元素的一种方式,这样当您的应用程序加载界面文件时,它可以加载正确的代码片段或执行它们。

它们通常是设置界面的一种更简单的方法 - 它们不是绝对必要的(您可以通过编程方式创建界面,而无需使用 XIB 文件),但如果您决定采用 XIB 路线,它们就是您的方式将您的界面与您的代码联系起来。

于 2013-01-22T16:51:13.707 回答
1

委托是一个对象,它被一个它声明自己是委托的对象委派了一些任务。假设一个对象执行了一些任务,然后需要通知“拥有”它的对象,可以这么说。为了让对象在任何条件下都能工作,不能让它知道自己应该联系什么类型的对象,所以我们设置了它的委托并遵守它的协议。设置对象的委托就像是在说“这是我希望你使用的对象与协议中声明的消息的联系。我保证该对象实际上实现了协议中的方法。” 例如,您可能会看到这个。

@protocol SpriteDelegateProtocol
    @required
    - (void) projectionMatrix;
    @optional
    - (void) animation:(int)animationIndex willCompleteFrameNumber:(int)frame forSprite:(id)sender;
@end

@interface Sprite
@property (nonatomic, assign) id<SpriteDelegateProtocol> delegate;
@end

我们的 sprite 对象的接口声明它有一个称为委托的属性,它的类型为id。它可以是任何对象,但必须遵守三角括号中的协议。如果它说它遵守协议,它必须实现@required 下声明的方法,并且可以实现@optional 下列出的方法。由我们来决定我们的委托是否真的使用类似respondsToSelector:. 如果我们有很多方法可以做到这一点,我们甚至可以存储返回值。

应用程序委托的特殊之处在于它是我们的 UIApplication 对象的委托。它接收有关应用程序状态的消息,例如applicationDidEnterBackground:. 您可以在此处查看我们的应用程序委托所遵循的协议中的哪些方法。

委托可以与任何对象一起使用。任何对象都可以说它具有要设置的委托属性,并且它必须具有如上所示的以下方法。该协议本质上是一个可移植的接口,可用于告诉另一个对象我们需要它来实现什么,以便我们可以调用所述方法将部分功能委托给它。我们可以在任务完成时通知我们的委托,要求它向我们提供信息(通常称为数据源而不是委托,以便如果您愿意它们可以是不同的对象),或者询问我们是否应该在全部。

出口是将在 NIB 或情节提要中实例化的视图连接到其控制器中的属性的一种方式。因此,如果您将 UIViewController 放入主故事板并将其类更改为 MyGreatControllerSubclass 然后继续在该控制器的视图中放置一个按钮,您可能希望将该按钮连接到控制器界面中的“插座”(属性),以便您可以稍后从控制器访问该按钮。

于 2013-01-22T16:53:17.180 回答
0

没有代表不是子类化的一种方式。我也是 Java 出身,做 OC 已经快 5 年了。

委托通常遵循与接口等效的协议。这样做的好处在于,它为您在如何实现委托所涵盖的内容方面提供了很大的灵活性。例如,您将看到可以通过扩展 UITableViewController 或实现委托来实现表视图。这样,如果您有一个组合视图,其中用户从一个表中选择项目并将它们放入另一个表中,您可以执行单个控制器并让它为两个视图执行委托。

考虑委托的最佳方式是作为面向消息/事件的回调的示例。你有没有听过这样的说法,框架与普通编程的不同之处在于,框架告诉你它想让你做什么来确保你寻求的结果?这就是代表团。昨晚我在做一个收藏视图,但无法打开编辑菜单。只需提供三种方法的委托,对菜单的调用方式、长按手势处理程序的位置等一无所知。

请注意,委托是使 OC 世界不需要依赖注入的粘合剂。我更喜欢他们。

于 2013-01-22T16:37:45.147 回答
0

代表是常见的设计模式(http://en.wikipedia.org/wiki/Delegation_pattern),它们不是特定于objective-c的。

Outlets 使控制器和视图(GUI)的绑定成为可能。你可能知道 MVC 范式(模型-视图-控制器)吗?因此,您使用 Interface Builder 构建您的 GUI(来自 MVC 的视图),并使用 outlet 将此 GUI 的元素(例如按钮、文本字段等)绑定到您的 Obj-C 代码(来自 MVC 的控制器)。

于 2013-01-22T16:48:45.150 回答
0

看看这篇文章:在 C# 代码中符合 Objective-C 的协议

不要担心标题中的“C#”这个词,你可以忽略那部分。这篇文章的主要部分讨论了 Objective-C 中的protocols和。delegates这可能会有所帮助。

于 2013-01-31T03:32:36.383 回答