Простой пример делегата? - PullRequest
8 голосов
/ 27 июня 2009

Хорошо, я программирую на target-C и использую Xcode. Я прочитал документацию на веб-сайте Apple и понимаю, что такое делегат, но когда я подхожу к той части, где говорится о том, как на самом деле реализовать методы делегата в коде, я просто запутываюсь, особенно когда они говорят что-то вроде «теперь реализуйте делегат». метод «. Может быть, это только я, но я точно не знаю, ГДЕ реализовать метод (будет ли файл AppDelegate.h / .m правильным местом в простой ситуации, когда у меня есть только классы ViewController и AppDelegate?). Я полагаю, что лучший способ для меня - это увидеть очень простой пример.

У меня есть некоторый код ниже, и мне было интересно, может ли кто-нибудь пройти и показать мне, как подключить делегат к ViewController, чтобы он отображал сумму? Извините, если код выглядит длинным, но это самый простой пример делегирования, который я мог придумать. Для аргументации и наличия меньшего количества кода для просмотра (чтобы мне было легче видеть, что происходит), скажем, сервер ServerClass * реализует сервер, а клиент ClientClass * реализует клиент. Оба уже связаны друг с другом и ждут, чтобы ввести их номер. Я записал то, что, по моему мнению, было бы правильно, но я точно знаю, что оно не завершено (что касается подключения делегата к серверу и клиенту). Одна вещь, которую я не знаю, куда поместить, - это объявления протоколов, поэтому, если кто-то мог бы решить эту простую проблему, это мне очень помогло бы, если бы я узнал, как делегат реализован в классе.

Кстати, я работаю с Peer Picker в новом GameKit iPhone SDK 3.0, если кто-то также хотел бы показать мне, что и с чем связано. Например, я на шаге 3 руководства Apple для 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

Ответы [ 2 ]

12 голосов
/ 27 июня 2009

Я не буду вдаваться в подробный анализ размещенного вами кода - наиболее полезный ответ, который вы можете получить, - это какое-то направление, касающееся общих принципов, выходящих за рамки конкретного примера кода. Вот общие принципы ...

  • Делегат - это объект, чьи объекты (как правило) вызываются для обработки или реагирования на определенные события или действия.
  • Вы должны «сообщить» объекту, который принимает делегата, которым вы хотите стать делегатом. Это можно сделать, позвонив [object setDelegate:self]; или установив object.delegate = self; в своем коде.
  • Объект, действующий в качестве делегата, должен реализовывать указанные методы делегата . Объект часто определяет методы либо в протоколе, либо в NSObject через категорию в качестве методов по умолчанию / пустых, либо в обоих. (Подход формального протокола, вероятно, более чистый, особенно теперь, когда Objective-C 2.0 поддерживает дополнительные методы протокола.)
  • Когда происходит соответствующее событие, вызывающий объект проверяет, реализует ли делегат соответствующий метод (используя -respondsToSelector:), и вызывает этот метод, если это так. Затем делегат может сделать все возможное, чтобы ответить, прежде чем вернуть управление вызывающей стороне.

В конкретном примере, с которым вы работаете, обратите внимание, что GKPeerPickerController имеет свойство с именем delegate, которое принимает объект типа id<GKPeerPickerControllerDelegate> , Это означает id (любой подкласс NSObject), который реализует методы в протоколе GKPeerPickerControllerDelegate. GKPeerPickerControllerDelegate , в свою очередь, определяет ряд методов делегатов и описывает, когда они будут вызваны. Если вы реализуете один или несколько из этих методов (в документации сказано, что все они являются необязательными, но ожидаются два) и зарегистрируетесь как делегат, эти методы будут вызваны. (Обратите внимание, что вам не нужно объявлять прототип метода в вашем файле .h, просто импортируйте заголовок протокола и внедрите метод в ваш файл .m.

1 голос
/ 27 июня 2009

Я изучаю ObjC и разработку для iPhone. Я бы не стал доходить до того, чтобы сказать, что я прекрасно понимаю делегатов и их использование. Ваше первое приложение для iPhone , найденное на портале для разработчиков на сайте Apple, подробно рассматривает очень простой пример, в котором используется делегат TextField для переопределения метода, при котором клавиатура исчезает при редактировании в TextField. сделанный. Например, если я могу вставить оттуда соответствующие фрагменты:

// 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

Здесь textFieldShouldReturn является методом, который является частью протокола UITextFieldDelegate. Насколько я понял, важно то, что в каком бы классе вы ни внедрили методы делегата, этот класс должен следовать протоколу этого конкретного делегата (так как имя протокола заключено в угловые скобки рядом с имя класса, от которого он наследует).

...