Qu'est-ce qu'un "délégué" dans le développement iPhone d'Objective C?
Voir ceci discussion
Un délégué autorise un objet à envoyer des messages à un autre objet lorsqu'un événement se produit. Par exemple, si vous téléchargez des données à partir d'un site Web de manière asynchrone à l'aide de la classe NSURLConnection class . NSURLConnection a trois délégués communs:
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
Un ou plusieurs de ces délégués sont appelés lorsque NSURLConnection rencontre un échec, s’achève correctement ou reçoit une réponse du site Web, respectivement.
Un délégué est un pointeur sur un objet avec un ensemble de méthodes que le détenteur du délégué sait comment appeler. En d'autres termes, il s'agit d'un mécanisme permettant d'activer des rappels spécifiques à partir d'un objet créé ultérieurement.
Un bon exemple est UIAlertView
. Vous créez un objet UIAlertView
pour afficher une boîte de message courte aux utilisateurs, leur donnant éventuellement le choix entre deux boutons, tels que "OK" et "Annuler". Le UIAlertView
a besoin d'un moyen de vous rappeler, mais il ne sait pas quel objet rappeler ni quelle méthode appeler.
Pour résoudre ce problème, vous pouvez envoyer votre pointeur self
à UIAlertView
en tant qu’objet délégué, et en échange, vous acceptez (en déclarant le UIAlertViewDelegate
dans le fichier d’en-tête de votre objet): implémenter des méthodes que UIAlertView
peut appeler, telles que alertView:clickedButtonAtIndex:
.
Découvrez this post pour une introduction rapide de haut niveau au modèle de conception des délégués et à d'autres techniques de rappel .
Les références:
Les délégués sont un modèle de conception; il n'y a pas de support de syntaxe ou de langage particulier.
Un délégué est simplement un objet vers lequel un autre objet envoie des messages lorsque certaines choses se produisent, afin que le délégué puisse gérer les détails spécifiques à l'application pour lesquels l'objet d'origine n'a pas été conçu. C'est une façon de personnaliser le comportement sans sous-classer.
Je pense que cet article Wikipedia le décrit le mieux: http://en.wikipedia.org/wiki/Delegation_pattern
C’est "juste" une implémentation d’un modèle de conception et très courant en Objective-C
S'il vous plaît! Consultez ci-dessous un didacticiel pas à pas pour comprendre le fonctionnement des délégués dans iOS.
J'ai créé deux ViewControllers (pour envoyer des données de l'un à l'autre)
Voici l'exemple de code qui peut vous aider.
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
J'essaie de l'élaborer à travers un programme simple
Deux classes
Étudiant.h
#import <Foundation/Foundation.h>
@interface Student : NSObject
@property (weak) id delegate;
- (void) studentInfo;
@end
Étudiant.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
Professeur.h
#import <Foundation/Foundation.h>
#import "Student.h>
@interface Teacher: NSObject
@property (strong,nonatomic) Student *student;
- (NSString *) teacherName;
- (id) initWithStudent:(Student *)student;
@end
Professeur.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;
}
EXPLICATION :::
De la méthode principale lorsque initWithStudent:student
Sera exécuté
1.1 La propriété de l'objet de l'enseignant ' student ' sera assignée à l'objet student.
1.2 self.student.delegate = self
means student object's delegate will points to teacher object
Depuis la méthode principale lorsque [student studentInfo]
Sera appelé
2.1 [self.delegate respondToSelector:@selector(teacherName)]
Ici, le délégué pointe déjà vers un objet enseignant afin qu'il puisse invoquer la méthode d'instance 'teacherName'.
2.2 donc [self.delegate performSelector:@selector(teacherName)]
s'exécutera facilement.
Il semble que l'objet Enseignant affecte un objet délégué à l'appel de sa propre méthode.
C'est une idée relative, où nous voyons cet objet étudiant appelé la méthode ' teacherName ', mais c'est fondamentalement fait par l'objet teacher lui-même.
Je pense que toutes ces réponses ont beaucoup de sens une fois que vous avez compris les délégués. Personnellement, je viens de C/C++ et, avant cela, des langages procéduraux tels que Fortran, etc., voici donc mon essai de 2 minutes sur la recherche d'analogues similaires dans le paradigme C++.
Si je devais expliquer les délégués à un programmeur C++/Java, je dirais
Que sont les délégués? Ce sont des pointeurs statiques vers des classes d'une autre classe. Une fois que vous avez affecté un pointeur, vous pouvez appeler des fonctions/méthodes dans cette classe. Par conséquent, certaines fonctions de votre classe sont "déléguées" (pointeur vers un monde en C++) à une autre classe.
Que sont les protocoles? Conceptuellement, il a la même fonction que le fichier d’en-tête de la classe que vous assignez en tant que classe déléguée. Un protocole est un moyen explicite de définir quelles méthodes doivent être implémentées dans la classe dont le pointeur a été défini en tant que délégué dans une classe.
Comment puis-je faire quelque chose de similaire en C++? Si vous avez essayé de le faire en C++, définissez les pointeurs sur les classes (objets) dans la définition de classe, puis connectez-les à d'autres classes qui fourniront des fonctions supplémentaires en tant que délégués de votre classe de base. Mais ce câblage doit être conservé dans le code et sera maladroit et sujet aux erreurs. Objective C suppose simplement que les programmeurs ne sont pas les mieux placés pour maintenir cette règle et fournit des restrictions au compilateur pour appliquer une mise en œuvre propre.
Le délégué déclenche les événements automatiques dans les objets C. Si vous définissez le délégué sur Object, il envoie le message à un autre objet par le biais des méthodes de délégation.
C'est un moyen de modifier le comportement d'une classe sans nécessiter de sous-classement.
Chaque objet ayant les méthodes de délégation. Ces méthodes de délégation sont déclenchées lorsque les objets particuliers participent à l'interaction de l'utilisateur et au cycle de déroulement du programme.
En termes simples, la délégation est un moyen de permettre aux objets d’interagir les uns avec les autres sans créer de fortes interdépendances.
Un délégué capture les actions d'enregistrement d'un utilisateur et effectue une action particulière en fonction de l'action d'enregistrement de l'utilisateur.
Delegate n'est rien d'autre qu'une instance d'Object dont nous pouvons appeler les méthodes au nom. et aide également à créer des méthodes dans rumtime de ces objets.