Простой пример делегата?
-
20-08-2019 - |
Вопрос
Хорошо, я программирую на Objective-C и использую Xcode.Я прочитал документацию на веб -сайте Apple и понимаю, что такое делегаты, но когда я прихожу к той части, где она говорит о том, как фактически внедрить методы делегатов в код, я просто запутался, особенно когда они говорят что -то вроде », теперь реализуйте делегата Метод. " Может быть, это только я, но я не знаю точно, где реализовать метод (будет ли файл appdelegate.h/.m был бы правильным местоположением в простой ситуации, когда у меня есть только класс ViewController и AppDelegate?).Я думаю, что лучший способ научиться для меня — это увидеть очень простой пример.
У меня есть код ниже, и мне интересно, сможет ли кто-нибудь пройти и показать мне, как подключить делегат к ViewController, чтобы он показывал сумму?Извините, если код выглядит длинным, но это самый простой пример делегирования, который я мог придумать.В качестве аргумента и чтобы было меньше кода для просмотра (чтобы мне было легче понять, что происходит), предположим, что ServerClass *server реализует сервер, а ClientClass *client реализует клиента.Оба уже подключены друг к другу и ждут ввода своего номера.Я записал то, что считаю правильным, но точно знаю, что оно неполное (что касается подключения делегата как к серверу, так и к клиенту).Единственное, что я не знаю, куда поместить, — это объявления протокола, поэтому, если кто-нибудь сможет решить эту простую задачу, это очень поможет мне в изучении того, как делегат реализуется в классе.
Кстати, я работаю с Peer Picker в новом GameKit iPhone SDK 3.0, если кто-то тоже захочет показать мне, что с чем связано.Например, я нахожусь в шаг 3 руководства Apple по Peer Picker.Теперь я не знаю, где в моем проекте идет шаг 5.Спасибо всем, кто может помочь мне понять реализацию этого делегата... до сих пор вы все были великолепны!
ПримерAppDelegate.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
ПримерAppDelegate.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
ПримерAppViewController.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
ПримерAppViewController.m
#import "ExampleAppViewcontroller.h"
@implementation ExampleAppViewController
@synthesize sum;
@synthesize num;
-(void) displaySum {
[sumfield setText: @"%i", sum];
}
@end
Решение
Я не буду вдаваться в подробный анализ опубликованного вами кода — самый полезный ответ, который вы можете получить, — это какое-то направление в отношении общих принципов, выходящих за рамки конкретного примера кода.Вот общие принципы...
- Делегат — это объект, объекты которого (обычно) вызываются для обработки или реагирования на определенные события или действия.
- Вы должны «сообщить» объекту, который принимает делегата, что вы хотите быть делегатом.Это делается путем вызова
[object setDelegate:self];
или настройкаobject.delegate = self;
в вашем коде. - Объект, действующий как делегат, должен реализовать указанный делегировать методы.Объект часто определяет методы либо в протоколе, либо в NSObject через категорию как методы по умолчанию/пустые, либо и то, и другое.(Подход с формальным протоколом, вероятно, стал чище, особенно теперь, когда Objective-C 2.0 поддерживает дополнительные методы протокола.)
- Когда происходит соответствующее событие, вызывающий объект проверяет, реализует ли делегат соответствующий метод (используя
-respondsToSelector:
) и вызывает этот метод, если это так.Затем делегат имеет право сделать все возможное, чтобы ответить, прежде чем вернуть управление вызывающему объекту.
Обратите внимание, что в конкретном примере, над которым вы работаете, GKPeerPickerController имеет свойство с именем delegate
который принимает объект типа id<GKPeerPickerControllerDelegate>
.Это означает id
(любой подкласс NSObject), реализующий методы класса GKPeerPickerControllerDelegate
протокол. GKPeerPickerControllerDelegate в свою очередь определяет ряд методов делегата и описывает, когда они будут вызываться.Если вы реализуете один или несколько из этих методов (в документации сказано, что все они необязательны, но ожидается два) и зарегистрируетесь в качестве делегата, эти методы будут вызваны.(Обратите внимание, что вам не нужно объявлять прототип метода в файле .h, просто импортируйте заголовок протокола и реализуйте метод в файле .m.
Другие советы
Я изучаю разработку 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
протокол.Насколько я это понимаю, важно то, что в каком бы классе вы ни реализовали методы делегата, этот класс должен следовать протоколу этого конкретного делегата (заключив имя протокола в угловые скобки сразу после имени класса, от которого он наследуется).