【问题标题】:Simple Delegate Example?简单的代表示例?
【发布时间】:2010-11-06 07:33:22
【问题描述】:

好的,我正在使用 Objective-C 编程并使用 Xcode。我已经阅读了 Apple 网站上的文档并了解什么是委托,但是当我谈到如何在代码中实际实现委托方法的部分时,我只是感到困惑,尤其是当他们说“现在实现委托的方法。”也许只有我一个人,但我不知道在哪里实现该方法(在我只有 ViewController 和 AppDelegate 类的简单情况下,AppDelegate.h/.m 文件是否是正确的位置?)。我想我真正学习的最好方法是看一个非常简单的例子。

我在下面有一些代码,我想知道是否有人可以通过并告诉我如何将委托连接到 ViewController 以便它显示总和?对不起,如果代码看起来很长,但这是我能想到的最简单的委托示例。为了争论和查看更少的代码(让我更容易看到发生了什么),假设 ServerClass *server 实现了一个服务器,而 ClientClass *client 实现了一个客户端。两者已经相互连接,正在等待输入他们的号码。我记下了我认为正确的内容,但我确定它不完整(就将委托连接到服务器和客户端而言)。我不知道把协议声明放在哪里,所以如果有人可以请做这个简单的问题,它将帮助我了解如何将委托实现到一个类中。

顺便说一句,如果有人还想向我展示什么连接到什么,我正在使用 iPhone SDK 3.0 的新 GameKit 中的 Peer Picker。例如,我在step 3 of the Apple guide for Peer Picker。现在,我不知道第 5 步在我的项目中的位置。感谢所有可以帮助我理解这个委托实现的人......到目前为止,你们都很棒!

ExampleAppDelegate.h

#import <UIKit/UIKit.h>

@class ExampleAppViewController;

@interface ExampleAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
    ExampleAppViewController *viewController;
    int sum;
}

@property (nonatomic, retain) sum;
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet ExampleAppViewController *viewController;

-(void) addNum:(int)num;
@end

ExampleAppDelegate.m

#import "ExampleAppDelegate.h"
#import "ExampleAppViewController.h"

@implementation ExampleAppDelegate

@synthesize window;
@synthesize viewController;


- (void)applicationDidFinishLaunching:(UIApplication *)application {    

    application.idleTimerDisabled = YES;

    // Override point for customization after app launch    
    [window addSubview:viewController.view];
    [window makeKeyAndVisible];
}


- (void)dealloc {
    [viewController release];
    [window release];
    [super dealloc];
}

-(void)addNum:(int)num {
    sum += num;
}

@end

ExampleAppViewController.h

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

@interface ExampleAppViewcontroller : NSObject {
        IBOutlet UILabel *sumField; // will display the total sum, one number entered //by the server and one entered by the client, on both iPhones after calculation

        int sum; // the total sum after addition;
        ServerClass *server; // some server
        ClientClass *client; // some client
        int num; // the number to add to sum
}

@property(nonatomic, assign) sum;
@property(nonatomic, retain) num;

-(void) displaySum;
@end

ExampleAppViewController.m

#import "ExampleAppViewcontroller.h"

@implementation ExampleAppViewController

@synthesize sum;
@synthesize num;

-(void) displaySum {
    [sumfield setText: @"%i", sum];
}

@end

【问题讨论】:

  • 如果我的代码中有语法问题,那是因为我现在不在 Mac 上,我必须在基于 Windows 的 PC 上输入。
  • 我确实阅读了有关语法的评论,但如果您不知道,我相信您不需要 (nonatomic, retain) 整数。不过,我可能是错的,据我所知,我根据我见过的代码和你不保留整数的事实来建立这个陈述。只需做@property sum;
  • 我相信首选的属性组合是 @property(nonatomic,assign) 用于不是指向对象的指针(整数、BOOL 等)

标签: objective-c delegates implementation


【解决方案1】:

我不会对您发布的代码进行任何详细的分析——您能得到的最有用的回复是一些关于超越特定代码示例的一般原则的方向。以下是一般原则...

  • 委托是一个对象,其对象(通常)被调用以处理或响应特定事件或操作。
  • 您必须“告诉”接受委托的对象您想成为委托。这可以通过调用 [object setDelegate:self]; 或在您的代码中设置 object.delegate = self; 来完成。
  • 作为委托的对象应该实现指定的委托方法。该对象通常在协议中定义方法,或通过类别在 NSObject 上定义为默认/空方法,或两者​​兼而有之。 (正式的协议方法可能更简洁,尤其是现在 Objective-C 2.0 支持可选协议方法。)
  • 当相关事件发生时,调用对象会检查委托是否实现了匹配的方法(使用-respondsToSelector:),如果实现则调用该方法。然后,在将控制权返回给调用者之前,委托人可以控制做任何必须响应的事情。

在您正在处理的具体示例中,请注意 GKPeerPickerController 有一个名为 delegate 的属性,它接受 id&lt;GKPeerPickerControllerDelegate&gt; 类型的对象。这意味着实现GKPeerPickerControllerDelegate 协议中的方法的id(NSObject 的任何子类)。 GKPeerPickerControllerDelegate 依次定义了许多委托方法并描述了它们何时被调用。如果您实现了其中一个或多个方法(文档说所有方法都是可选的,但需要两个)并注册为委托,则将调用这些方法。 (请注意,您不需要在 .h 文件中声明方法原型,只需导入协议头并在 .m 文件中实现方法即可。

【讨论】:

  • 感谢您的帮助。我现在对委派有了更好的理解。
【解决方案2】:

我正在学习 ObjC 和 iPhone 开发。我不会说我完全理解代表及其使用。 Your First iPhone Application,可在 Apple 网站上的开发人员门户上找到,详细介绍了一个非常简单的示例,该示例利用 TextField 的委托重写了一种方法,使在 TextField 上的编辑完成时键盘消失。例如,如果我可以从那里粘贴相关的 sn-ps:

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

@interface MyViewController : UIViewController <UITextFieldDelegate> {
        UITextField *textField;
        UILabel *label;
        NSString *string;
}

@property (nonatomic, retain) IBOutlet UITextField *textField;
@property (nonatomic, retain) IBOutlet UILabel *label;
@property (nonatomic, copy) IBOutlet NSString *string;

- (IBAction)changeGreeting:(id)sender;

@end


// MyViewController.m
#import "MyViewController.h"

@implementation MyViewController

@synthesize textField;
@synthesize label;
@synthesize string;

- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
        if (theTextField == textField) {
                [textField resignFirstResponder];
        }
        return YES;
}

@end

在这里,textFieldShouldReturnUITextFieldDelegate 协议的一部分的方法。据我了解,重要的是无论您在哪个类中实现委托方法,该类必须遵循该特定委托的协议(通过将协议名称括在紧挨着的尖括号中它继承的类的名称)。

【讨论】:

  • 这清楚地说明了在何处以及如何包含委托协议。但是有一个问题,在设置协议(在.h文件中的尖括号中)并且我已经声明了委托(即picker.delegate = self)之后,这是否意味着picker现在已经继承了所有协议方法或做在我开始使用带有选择器的协议方法之前,我需要添加一些其他代码行吗?
  • 据我了解,如果一个类遵循委托协议,它可以覆盖委托协议定义的所有方法。
  • 当您采用协议时(无论是用于委托还是其他任何东西),您都不会“继承”任何变量或方法实现。 (这只发生在您扩展父类时,例如 UIViewController 或 NSObject。)协议就像 Java 接口:采用协议是您将实现(至少是必需的)它声明的方法的承诺。协议用于建立对调用者可能要求您的对象实例执行的操作的正式期望,默认情况下,编译器会警告您未实现的必需协议方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-02-02
  • 2012-05-19
  • 1970-01-01
  • 2017-09-27
  • 2013-01-13
  • 1970-01-01
  • 2014-09-18
相关资源
最近更新 更多