Простой пример делегата?

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

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

Кстати, я работаю с Peer Picker в новом GameKit iPhone SDK 3.0, если кто-то также хотел бы показать мне, что с чем связано. Например, я нахожусь вшаг 3 из руководства Apple для Peer Picker, Теперь я не знаю, куда пойдет шаг 5 в моем проекте. Спасибо всем, кто может помочь мне понять реализацию этого делегата ... вы все были великолепны!

ExampleAppDelegate.h

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

ExampleAppDelegate.m

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

ExampleAppViewController.h

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

ExampleAppViewController.m

<code>#import "ExampleAppViewcontroller.h"

@implementation ExampleAppViewController

@synthesize sum;
@synthesize num;

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

@end
</code>
 Jorge Israel Peña27 июн. 2009 г., 04:04
Я прочитал комментарий о синтаксисе, но в случае, если вы не знали, я думаю, что вам не нужно (неатома, сохранить) для целого числа. Хотя я могу ошибаться, я основываю это утверждение на коде, который я видел, и на том факте, что, насколько я знаю, вы не сохраняете целые числа. Просто наберите @property sum;
 Tim27 июн. 2009 г., 05:09
Я считаю, что предпочтительным сочетанием свойств является @property (nonatomic, assign) для вещей, которые не являются указателями на объекты (целые числа, BOOL и т. Д.)
 Josh Bradley27 июн. 2009 г., 03:06
Если в моем коде есть какая-то проблема с синтаксисом, то это потому, что я сейчас не на своем Mac, я должен был напечатать его на компьютере под управлением Windows.

Ответы на вопрос(2)

чтобы сказать, что я прекрасно понимаю делегатов и их использование. Ваше первое приложение для 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 протокол. Насколько я понял, важно то, что в каком бы классе вы ни реализовывали методы делегата, этот классдолже следуйте протоколу этого конкретного делегата (указав имя протокола в угловых скобках непосредственно рядом с именем класса, от которого он наследует).

 Josh Bradley27 июн. 2009 г., 19:47
Это многое прояснило о том, где и как включать протоколы делегатов. Однако один вопрос: после того, как протокол был установлен (в угловых скобках в файле .h), и я объявил делегата (то есть picker.delegate = self), означает ли это, что средство выбора теперь унаследовало все методы протокола или Мне нужно добавить еще одну строку кода, которая делает это, прежде чем я начну использовать методы протокола с помощью средства выбора?
 ayaz27 июн. 2009 г., 20:24
Насколько я понимаю, если класс следует протоколу делегата, он может переопределить все методы, определенные протоколом делегата.
 Quinn Taylor01 июл. 2009 г., 18:27
Когда вы принимаете протокол (будь то делегат или что-то еще), вы не «наследуете» какие-либо переменные или реализации методов. (Это происходит только тогда, когда вы расширяете родительский класс, такой как UIViewController или NSObject.) Протокол подобен интерфейсу Java: принятие протокола - это обещание, которое вы будете реализовывать (по крайней мере, необходимые) методы, которые он объявляет. Протоколы используются для установления формальных ожиданий того, что вызывающая сторона может запрашивать у экземпляров вашего объекта, и по умолчанию компилятор предупредит вас о невыполненных обязательных методах протокола.
Решение Вопроса

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

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

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

 Josh Bradley30 июн. 2009 г., 17:13
Спасибо за вашу помощь. Теперь я понимаю делегирование намного лучше.

Ваш ответ на вопрос