【问题标题】:Objective-c Delegates can't understand how to use themObjective-c Delegates 无法理解如何使用它们
【发布时间】:2013-07-30 18:52:15
【问题描述】:

我对委托的使用感到迷茫。 好的,它们用于在对象之间传递值,假设 ClassA 需要将值传递给 ClassB,我们应该使用委托(如果我至少知道的话)。

假设我有一个 ViewControllerA 有一个文本字段和一个按钮,以及一个 ViewControllerB 有一个标签。要将从 VControllerA 中的文本字段保存的数据传递给 VControllerB,我可以使用委托...

让我们看看第一节课

//ViewControllerA
#import <UIKit/UIKit.h>

@interface ViewControllerA : UIViewController {
IBOutlet UITextField *tf_text;
IBOutlet UIButton *but_add;
}

@property (nonatomic, retain) IBOutlet UITextField *tf_text;
@property (nonatomic, retain) IBOutlet UIButton *but_add;

-(IBAction)addAction:(id)sender;

@end

好的,这是另一个

//ViewControllerB
#import "ViewControllerA.h"

@interface ViewControllerB : ViewController {

IBOutlet UILabel *_label;

}

@property (nonatomic, retain) IBOutlet UILabel *_label;

@end

好的,现在我开始迷路了。 使用此协议的正确方法是什么?假设我想把它作为一个新文件 控制器ADelegate.h

我应该如何传递数据?

我越来越喜欢它了,我看过很多在线教程,但我仍然无法真正了解如何使用它

【问题讨论】:

标签: objective-c class delegates protocols


【解决方案1】:

我认为你对代表的理解还是有点偏离标准,如果你想在视图控制器之间传递数据,那么JuJoDi's link 就是你想要的。

但是委托可以被视为一种回调,当“子”对象发生某些事情时,可以让“父”对象有机会执行某些代码。

例如 UIScrollView 有一个委托方法scrollViewDidScroll: 告诉它的委托它已经滚动并且可以运行一些代码。大多数时候你会去scrollView.delegate = self,这意味着self的对象(通常是你写这个语句的视图控制器)正在成为滚动视图的代表,这意味着它将接收来自scrollviews 委托方法(在 UIScrollViewDelegate 协议中定义,但除非您想编写自己的委托,否则您无需担心)。

希望可以稍微澄清一下,但简而言之,委托不仅用于传递数据(即使它们有参数,它们实际上是用于不同的目的),它们用于在发生某些事情时运行代码“父”对象(或类之外的任何东西)可能需要了解的对象

【讨论】:

    【解决方案2】:

    正如 Apple 在其 IOS tutorial 中指出的那样,委托的存在不是为了将数据从您的视图的一部分传递到另一部分,而是让您的应用程序在用户导致事件发生时做出反应。例如,用户正在编辑某些东西,然后试图关闭编辑窗口。系统将向窗口的委托发送windowShouldClose: 消息。如果代理存在并且可以接受消息,则代理可以警告用户他有未保存的编辑并询问他是否关闭编辑窗口。

    委托通常被声明为id &lt;NSWindowDelegate&gt; 之类的东西并实现该协议。

    您的控制器应该自己传递数据。这只是普通的编程。

    【讨论】:

    • 这是我的疑问...我正在阅读网络上的一些委托教程...但对我来说这很奇怪...传递这些数据,我只会使用传递参数的常规方法。 ..
    • 是的。您的控制器相互交谈,并将数据推送回视图和模型。委托(您可以让控制器成为它自己的委托)处理基于用户所做的事情发生的系统事件。您的任何代码都不会调用windowShouldClose:。如果该消息存在并且可以响应,系统会将该消息发送给您的代理。
    【解决方案3】:

    如果您将信息从子级传递给父级,则使用委托。在您的情况下,如果 ViewControllerA 是 ViewControllerB 的孩子,那么您将需要一个委托。我不明白为什么你需要把它作为一个新文件来做。 您需要做的就是在您的子 (ViewControllerA) 头文件中执行以下操作:

    @class ViewControllerA;
    @protocol ViewControllerADelegate/*just naming your delegate */ <NSObject>
    //list methods that you will be using from your parent ex. -(void)setLabel;
    

    别忘了在你的界面中为你的委托设置一个属性

    @property(nonatomic, strong)id delegate;
    

    现在,在您的 ViewControllerA 实现文件中,您需要访问父级 (ViewControllerB) 中的方法,您可以在 IBAction 中执行此操作

    -(IBAction)addAction:(id)Sender {
    [self.delegate setLabel];
    

    现在将您的 ViewControllerB 设置为委托。 在标题中确保有您放置在您孩子的协议中的方法。还要确保孩子已导入。

    #import "ViewControllerA"
    

    界面后结束前

    -(void)setLabel;
    

    在 ViewController B 的实现中(最重要的)!

    -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {
    ViewControllerA * view = [[[segue destinationViewController] viewControllers] objectAtIndex:0];
    [view setDelegate:self];
    

    【讨论】:

    • 如果 B 是 A 的儿子,我不能只使用常规方法来传递参数吗?为什么要使用委托?
    • 如果 B 是 A 的儿子,那么 A 可以从 A 那里得到任何方法。很好的思考方式是:父母可以告诉孩子做什么,但孩子不能告诉家长该怎么办。这就是我们委派孩子的原因。
    猜你喜欢
    • 1970-01-01
    • 2011-03-20
    • 2010-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多