2009-06-27 3 views
8

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

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

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

Если в моем коде есть какая-то синтаксическая проблема, то это потому, что я не на своем Mac прямо сейчас, я должен был ввести его на ПК на базе Windows. –

+0

Я прочитал комментарий о синтаксисе, но в случае, если вы этого не знали, я считаю, что вам не нужно (неатомное, сохранить) для целого числа. Я мог ошибаться, но я основываю это утверждение на коде, который я видел, и на том факте, что вы не сохраняете целые числа, насколько мне известно. Просто сделайте @property sum; –

+0

Я считаю, что предпочтительным сочетанием свойств является @property (nonatomic, assign) для вещей, которые не являются указателями на объекты (целые числа, BOOL и т. Д.). – Tim

ответ

12

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

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

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

+0

Спасибо за вашу помощь. Теперь я понимаю делегацию намного лучше. –

1

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

+0

Это объясняет, где и как включать протоколы делегатов. Один вопрос, хотя после того, как протокол установлен (в скобках угла в файле .h), и я объявил делегата (т.е. picker.delegate = self), означает ли это, что теперь сборщик унаследовал все методы протокола или сделал Мне нужно добавить еще одну строку кода, которая делает это, прежде чем я начну использовать методы протокола с помощью сборщика? –

+0

Насколько я понимаю, если класс следует за протоколом делегата, он может переопределить все методы, определенные протоколом делегирования. – ayaz

+0

Когда вы принимаете протокол (будь то для делегата или что-то еще), вы не «наследуете» любые переменные или реализации методов. (Это происходит только при расширении родительского класса, такого как UIViewController или NSObject.) Протокол похож на интерфейс Java: принятие протокола - это обещание, которое вы реализуете (по крайней мере, требуемые) методы, которые он объявляет. Протоколы используются для установления официальных ожиданий того, что вызывающий может запрашивать экземпляры вашего объекта, и по умолчанию компилятор предупредит вас о нереализованных требуемых методах протокола. –

Смежные вопросы