2010-03-28 9 views
65

Che cos'è un "delegato" nello sviluppo di iPhone di Objective C?Che cos'è un "delegato" nello sviluppo di iPhone di Objective C?

+0

Questo sembra essere un duplicato di http://stackoverflow.com/questions/1349706/little-confused-on-delegates-in-objective-c e possibilmente http://stackoverflow.com/questions/1788032/what -is-delegate-and-delegate-methods –

+0

Vedere anche: http://stackoverflow.com/questions/645449/how-to-use-custom-delegates-in-objective-c, http://stackoverflow.com/ domande/626.898/how-do-i-create-delegates-in-obiettivo-c, http://stackoverflow.com/questions/1015608/how-to-perform-callbacks-in-objective-c e http://stackoverflow.com/questions/1408774/can-someone-explain-what-a-delegate-is-with-an-example –

risposta

55

Vedere questo discussion

Un delegato consente un oggetto per inviare messaggi a un altro oggetto quando si verifica un evento. Ad esempio, se stai scaricando dati da un sito Web in modo asincrono utilizzando lo NSURLConnection class. NSURLConnection ha tre delegati comuni:

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 
- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 

Uno o più di questi delegati andranno chiamati quando NSURLConnection riscontra un errore, termina con successo, o ha ricevuto una risposta dal sito web, rispettivamente.

+4

Questo tipo di ascoltatore è simile ad Android? –

+0

@JordanHochstetler sembra che il delegato sia ESATTAMENTE l'ascoltatore –

19

I delegati sono uno schema di progettazione; non esiste una sintassi speciale o supporto linguistico.

Un delegato è solo un oggetto a cui un altro oggetto invia messaggi quando si verificano determinati eventi, in modo che il delegato possa gestire i dettagli specifici dell'app per i quali l'oggetto originale non è stato progettato. È un modo di personalizzare il comportamento senza sottoclassi.

+2

Quindi, in sostanza, è il modo OOP di implementare un callback? –

+0

@DanielSloof Stavo pensando lo stesso ... – Mirko

77

Un delegato è un puntatore a un oggetto con una serie di metodi che il titolare del delegato sa come chiamare. In altre parole, è un meccanismo per abilitare callback specifici da un oggetto creato successivamente.

A un buon esempio è UIAlertView. Si crea un oggetto UIAlertView per mostrare una casella di messaggio breve agli utenti, possibilmente dando loro una scelta con due pulsanti come "OK" e "Annulla". Lo UIAlertView necessita di un modo per richiamarti, ma non ha informazioni su quale oggetto richiamare e quale metodo chiamare.

Per risolvere questo problema, è possibile inviare il puntatore self-UIAlertView come un oggetto delegato, e in cambio l'utente accetta (dichiarando il UIAlertViewDelegate nel file di intestazione del vostro oggetto) per implementare alcuni metodi che UIAlertView può chiamare, come alertView:clickedButtonAtIndex: .

Partenza this post per un rapido alto livello intro per il modello di progettazione delegato e altre tecniche di callback.

Riferimenti:

1

Il delegato spara gli eventi automatici di oggetti C. Se si imposta il delegato di opporsi, invia il messaggio a un altro oggetto tramite i metodi delegati.

È un modo per modificare il comportamento di una classe senza richiedere la sottoclasse.

Ogni oggetto con i metodi delegati.Questi metodi delegati si attivano quando gli oggetti specifici partecipano all'interazione dell'utente e al ciclo del flusso del programma.

In parole povere: la delega è un modo per consentire oggetti di interagire con l'altro senza creare forti interdipendenze tra di loro.

1

Un delegato acquisisce le azioni di registrazione di un utente ed esegue un'azione specifica in base all'azione di tocco dell'utente.

0

delegato non è altro che istanza di oggetto che possiamo chiamare i metodi per conto di che gli oggetti. e aiuta anche a creare metodi nel rumtime di quegli oggetti.

3

Per favore! controlla sotto semplice tutorial passo passo per capire come i delegati funzionano in iOS.

Delegate in iOS

ho creato due ViewControllers (per l'invio di dati da uno all'altro)

  1. FirstViewController implementare delegato (che fornisce i dati).
  2. SecondViewController dichiara il delegato (che riceverà i dati).

Ecco il codice di esempio può aiutare.

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 
+0

Ciao RDC, questo codice non funziona, puoi provare per favore. –

2

Credo che tutte queste risposte fanno un sacco di senso una volta capito delegati. Personalmente sono venuto dalla terra di C/C++ e prima di quei linguaggi procedurali come Fortran ecc. Ecco quindi i miei 2 minuti per trovare analoghi analoghi nel paradigma C++.

Se dovessi spiegare i delegati a un programmatore ++/Java C direi

Quali sono i delegati? Questi sono puntatori statici alle classi all'interno di un'altra classe. Una volta assegnato un puntatore, puoi chiamare funzioni/metodi in quella classe. Quindi alcune funzioni della classe sono "delegate" (in C++ world - puntatore a da un puntatore di oggetto classe) a un'altra classe.

Quali sono i protocolli? Concettualmente serve come scopo simile al file di intestazione della classe che si assegna come classe delegata. Un protocollo è un modo esplicito di definire quali metodi devono essere implementati nella classe il cui puntatore è stato impostato come delegato all'interno di una classe.

Come posso fare qualcosa di simile in C++? Se hai provato a farlo in C++, definirai i puntatori alle classi (oggetti) nella definizione della classe e poi li collegherai ad altre classi che forniranno funzioni aggiuntive come delegati alla tua classe base. Ma questo cablaggio deve essere inserito nel codice e sarà goffo e soggetto a errori. L'obiettivo C presume semplicemente che i programmatori non siano i migliori nel mantenere questa deciplina e fornisce le restrizioni del compilatore per imporre un'implementazione pulita.

3

cerco di elaborare attraverso semplice programma

due Categorie

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; 
} 

SPIEGAZIONE :::

  1. Da metodo principale quando initWithStudent:student eseguirà

    1.1 La proprietà dell'oggetto dell'insegnante 'studente' sarà assegnata con oggetto studente.

    1,2 self.student.delegate = self

    means student object's delegate will points to teacher object 
    
  2. Da metodo principale quando [student studentInfo] saranno chiamati

    2.1 [self.delegate respondToSelector:@selector(teacherName)] Qui delegato punta già all'oggetto insegnante in modo da poter richiamare il metodo di istanza "teacherName" .

    2.2 so [self.delegate performSelector:@selector(teacherName)] verrà eseguito facilmente.

Sembra che l'oggetto insegnante assegni delegato all'oggetto studente per chiamare il proprio metodo.

E 'un'idea relativa, dove si vede che oggetto studente chiamato 'teacherName' metodo, ma è fondamentalmente fatto da insegnante oggetto stesso.

Problemi correlati