Что такое "делегат" в разработке Objective C для iPhone?
Что такое "делегат" в разработке Objective C для iPhone?
10 ответов
Смотрите это обсуждение
Делегат позволяет одному объекту отправлять сообщения другому объекту, когда происходит событие. Например, если вы загружаете данные с веб-сайта асинхронно, используя класс NSURLConnection. NSURLConnection имеет три общих делегата:
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
Один или несколько из этих делегатов будут вызваны, когда NSURLConnection обнаружит сбой, завершится успешно или получит ответ от веб-сайта соответственно.
Делегат - это указатель на объект с набором методов, которые владелец делегата знает, как вызывать. Другими словами, это механизм для включения определенных обратных вызовов от созданного позже объекта.
Хороший примерUIAlertView
, Вы создаете UIAlertView
объект, чтобы показать пользователям окно с коротким сообщением, возможно, предоставив ему выбор с помощью двух кнопок, таких как "ОК" и "Отмена". UIAlertView
нужен способ перезвонить вам, но у него нет информации о том, какой объект вызывать и какой метод вызывать.
Чтобы решить эту проблему, вы можете отправить свой self
указатель на UIAlertView
как объект делегата, и в обмен вы соглашаетесь (объявив UIAlertViewDelegate
в файле заголовка вашего объекта), чтобы реализовать некоторые методы, которые UIAlertView
можно позвонить, например, alertView:clickedButtonAtIndex:
,
Прочтите этот пост, чтобы быстро познакомиться с шаблоном проектирования делегатов и другими методами обратного вызова.
Рекомендации:
Делегаты - это шаблон дизайна; нет специального синтаксиса или языковой поддержки.
Делегат - это просто объект, которому другой объект отправляет сообщения, когда происходят определенные вещи, так что делегат может обрабатывать специфичные для приложения детали, для которых исходный объект не был разработан. Это способ настройки поведения без создания подклассов.
Я думаю, что эта статья Википедии описывает это лучше всего: http://en.wikipedia.org/wiki/Delegation_pattern
Это "просто" реализация шаблона проектирования и очень распространенная в Objective-C
Я думаю, что все эти ответы имеют большой смысл, когда вы понимаете делегатов. Лично я приехал из страны Си / Си ++ и до этого процедурных языков, таких как Фортран и т. Д., Так что вот мои 2 минуты, чтобы найти аналогичные аналоги в парадигме Си ++.
Если бы я должен был объяснить делегатов программисту на C++/Java, я бы сказал,
Что такое делегаты? Это статические указатели на классы в другом классе. Как только вы назначите указатель, вы можете вызывать функции / методы в этом классе. Hence some functions of your class are "delegated" (In C++ world - pointer to by a class object pointer) to another class.
Какие протоколы? Conceptually it serves as similar purpose as to the header file of the class you are assigning as a delegate class. Протокол - это явный способ определения того, какие методы должны быть реализованы в классе, указатель которого был задан как делегат внутри класса.
Как я могу сделать что-то подобное в C++? Если бы вы попытались сделать это в C++, вы должны определить указатели на классы (объекты) в определении класса, а затем связать их с другими классами, которые будут предоставлять дополнительные функции в качестве делегатов для вашего базового класса. Но эта проводка должна поддерживаться в коде и будет неуклюжей и подверженной ошибкам. Цель C просто предполагает, что программисты не лучше всего поддерживают эту дешифровку, и предоставляет ограничения компилятора для обеспечения чистой реализации.
Пожалуйста! посмотрите ниже простое пошаговое руководство, чтобы понять, как делегаты работают в iOS.
Я создал два ViewController (для отправки данных от одного к другому)
- FirstViewController реализует делегат (который предоставляет данные).
- SecondViewController declare the delegate (which will receive data).
Here is the sample code may help you.
AppDelegate.h
#import <UIKit/UIKit.h>
@class FirstViewController;
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) FirstViewController *firstViewController;
@end
AppDelegate.m
#import "AppDelegate.h"
#import "FirstViewController.h"
@implementation AppDelegate
@synthesize firstViewController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
//create instance of FirstViewController
firstViewController = [[FirstViewController alloc] init];
//create UINavigationController instance using firstViewController
UINavigationController *firstView = [[UINavigationController alloc] initWithRootViewController:firstViewController];
//added navigation controller to window as a rootViewController
self.window.rootViewController = firstView;
[self.window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
@end
FirstViewController.h
#import <UIKit/UIKit.h>
#import "SecondViewController.h"
@interface FirstViewController : UIViewController<MyDelegate>
@property (nonatomic, retain) NSString *mesasgeData;
@property (weak, nonatomic) IBOutlet UITextField *textField;
@property (weak, nonatomic) IBOutlet UIButton *nextButton;
- (IBAction)buttonPressed:(id)sender;
@property (nonatomic, strong) SecondViewController *secondViewController;
@end
FirstViewController.m
#import "FirstViewController.h"
@interface FirstViewController ()
@end
@implementation FirstViewController
@synthesize mesasgeData;
@synthesize textField;
@synthesize secondViewController;
#pragma mark - View Controller's Life Cycle methods
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - Button Click event handling method
- (IBAction)buttonPressed:(id)sender {
//get the input data from text feild and store into string
mesasgeData = textField.text;
//go keypad back when button clicked from textfield
[textField resignFirstResponder];
//crating instance of second view controller
secondViewController = [[SecondViewController alloc]init];
//it says SecondViewController is implementing MyDelegate
secondViewController.myDelegate = self;
//loading new view via navigation controller
[self.navigationController pushViewController:secondViewController animated:YES];
}
#pragma mark - MyDelegate's method implementation
-(NSString *) getMessageString{
return mesasgeData;
}
@end
SecondViewController.h
//declare our own delegate
@protocol MyDelegate <NSObject>
-(NSString *) getMessageString;
@end
#import <UIKit/UIKit.h>
@interface SecondViewController : UIViewController
@property (weak, nonatomic) IBOutlet UILabel *messageLabel;
@property (nonatomic, retain) id <MyDelegate> myDelegate;
@end
SecondViewController.m
#import "SecondViewController.h"
@interface SecondViewController ()
@end
@implementation SecondViewController
@synthesize messageLabel;
@synthesize myDelegate;
- (void)viewDidLoad
{
[super viewDidLoad];
messageLabel.text = [myDelegate getMessageString];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
@end
Я пытаюсь разработать это с помощью простой программы
Два класса
Student.h
#import <Foundation/Foundation.h>
@interface Student : NSObject
@property (weak) id delegate;
- (void) studentInfo;
@end
Student.m
#import "Student.h"
@implementation Student
- (void) studentInfo
{
NSString *teacherName;
if ([self.delegate respondsToSelector:@selector(teacherName)]) {
teacherName = [self.delegate performSelector:@selector(teacherName)];
}
NSLog(@"\n Student name is XYZ\n Teacher name is %@",teacherName);
}
@end
Teacher.h
#import <Foundation/Foundation.h>
#import "Student.h>
@interface Teacher: NSObject
@property (strong,nonatomic) Student *student;
- (NSString *) teacherName;
- (id) initWithStudent:(Student *)student;
@end
Teacher.m
#import "Teacher.h"
@implementation Teacher
- (NSString *) teacherName
{
return @"ABC";
}
- (id) initWithStudent:(Student *)student
{
self = [ super init];
if (self) {
self.student = student;
self.student.delegate = self;
}
return self;
}
@end
main.m
#import <Foundation/Foundation.h>
#import "Teacher.h"
int main ( int argc, const char* argv[])
{
@autoreleasepool {
Student *student = [[Student alloc] init];
Teacher *teacher = [[Teacher alloc] initWithStudent:student];
[student studentInfo];
}
return 0;
}
EXPLANATION:::
From main method when
initWithStudent:student
выполнит1.1 Teacher's object's property 'student' will be assigned with student object.
1.2
self.student.delegate = self
means student object's delegate will points to teacher object
From main method when
[student studentInfo]
будет называться2,1
[self.delegate respondToSelector:@selector(teacherName)]
Here delegate already points to teacher object so it can invoke 'teacherName' instance method.2.2 so
[self.delegate performSelector:@selector(teacherName)]
will execute easily.
Похоже, что объект Учителя назначает делегат объекту студента для вызова его собственного метода.
It is a relative idea, where we see that student object called 'teacherName' method but it is basically done by teacher object itself.
Делегат запускает автоматические события в объектах C. Если вы установите делегат в Object, он отправляет сообщение другому объекту через методы делегата.
Это способ изменить поведение класса, не требуя подклассов.
Каждый объект имеет методы делегата. Эти методы делегата запускаются, когда конкретные объекты принимают участие во взаимодействии с пользователем и цикле выполнения программы.
Проще говоря: делегирование - это способ позволить объектам взаимодействовать друг с другом без создания сильных взаимозависимостей между ними.
Делегат фиксирует действия пользователя по записи и выполняет определенное действие в соответствии с действием пользователя.
Делегат - это не что иное, как экземпляр объекта, который мы можем вызывать методами от имени этих объектов. а также помогает создавать методы в rumtime тех объектов.