2010-03-28 10 views
65

उद्देश्य सी के आईफोन विकास में "प्रतिनिधि" क्या है?उद्देश्य सी के आईफोन विकास में "प्रतिनिधि" क्या है?

+0

यह http://stackoverflow.com/questions/1349706/little-confused-on-delegates-in-objective-c और संभवतः http://stackoverflow.com/questions/1788032/what का डुप्लिकेट प्रतीत होता है -इस-प्रतिनिधि-और-प्रतिनिधि-विधियां –

+0

यह भी देखें: http://stackoverflow.com/questions/645449/how-to-use-custom-delegates-in-objective-c, http://stackoverflow.com/ प्रश्न/6268 9 8/कैसे-करें-मैं-निर्माण-प्रतिनिधि-इन-ऑब्जेक्ट-सी, http://stackoverflow.com/questions/1015608/how-to-perform-callbacks-in-objective-c, और http://stackoverflow.com/questions/1408774/can-someone-explain-what-a-delegate-is-with-an-example –

उत्तर

55

इस discussion

एक प्रतिनिधि की अनुमति देता है देखें जाता है:

+4

क्या यह एंड्रॉइड में श्रोता की तरह है? –

+0

@ जोर्डन होचस्टेलर प्रतिनिधि की तरह दिखता है कि श्रोता –

19

प्रतिनिधि एक डिजाइन पैटर्न हैं; कोई विशेष वाक्यविन्यास या भाषा समर्थन नहीं है।

एक प्रतिनिधि केवल एक वस्तु है कि एक और वस्तु कुछ चीजें होने पर संदेश भेजती है, ताकि प्रतिनिधि ऐप-विशिष्ट विवरणों को संभाल सकें, मूल वस्तु को डिजाइन नहीं किया गया था। यह सबक्लासिंग के बिना व्यवहार को अनुकूलित करने का एक तरीका है। http://en.wikipedia.org/wiki/Delegation_pattern

यह "बस" एक डिजाइन पैटर्न के एक कार्यान्वयन और में बहुत आम ऑब्जेक्टिव-सी

+2

तो अनिवार्य रूप से यह कॉलबैक लागू करने का ओओपी-तरीका है? –

+0

@DanielSloof मैं वही सोच रहा था ... – Mirko

5

मैं इस विकिपीडिया लेख यह सबसे अच्छा वर्णन लगता है जब कोई घटना होती है तो किसी ऑब्जेक्ट को संदेश भेजने के लिए एक ऑब्जेक्ट। उदाहरण के लिए, यदि आप NSURLConnection class का उपयोग करके एक वेबसाइट से डेटा को अतुल्य रूप से डाउनलोड कर रहे हैं। ,

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

ऐसे एक या अधिक प्रतिनिधियों जब NSURLConnection एक विफलता का सामना करना पड़ता कहा जाता हो जाएगा के सफलतापूर्वक पूर्ण होने पर, या वेब साइट, क्रमशः से एक प्रतिक्रिया प्राप्त किया: NSURLConnection तीन आम प्रतिनिधियों है।

77

एक प्रतिनिधि एक ऑब्जेक्ट के लिए एक सूचक है जो प्रतिनिधि-धारक जानता है कि कॉल कैसे करें। दूसरे शब्दों में, यह बाद में बनाई गई ऑब्जेक्ट से विशिष्ट कॉलबैक को सक्षम करने के लिए एक तंत्र है।

अच्छा उदाहरण UIAlertView है। आप उपयोगकर्ताओं को एक संक्षिप्त संदेश बॉक्स दिखाने के लिए UIAlertView ऑब्जेक्ट बनाते हैं, संभवतः उन्हें "ठीक" और "रद्द करें" जैसे दो बटनों के साथ एक विकल्प प्रदान करते हैं। UIAlertView आपको वापस कॉल करने के लिए एक तरीका की आवश्यकता है, लेकिन इसमें कोई जानकारी नहीं है कि किस ऑब्जेक्ट को वापस कॉल करना है और किस विधि को कॉल करना है।

इस समस्या को हल करने के लिए, आप एक प्रतिनिधि वस्तु के रूप में UIAlertView करने के लिए अपने self सूचक भेज सकते हैं, और बदले में आप (अपने ऑब्जेक्ट के हेडर फाइल में UIAlertViewDelegate की घोषणा के द्वारा) इस बात से सहमत कुछ तरीकों कि UIAlertView कॉल कर सकते हैं, इस तरह के alertView:clickedButtonAtIndex: के रूप में लागू करने के लिए ।

के लिए प्रतिनिधि डिजाइन पैटर्न और अन्य कॉलबैक तकनीकों के लिए एक त्वरित उच्च स्तरीय परिचय देखें।

संदर्भ:

1

प्रतिनिधि वस्तुओं में स्वत: घटनाओं आग सी आप वस्तु के लिए प्रतिनिधि सेट करते हैं, यह करने के लिए संदेश भेजता है प्रतिनिधि तरीकों के माध्यम से एक और वस्तु।

यह सब क्लासिंग की आवश्यकता के बिना कक्षा के व्यवहार को संशोधित करने का एक तरीका है।

प्रत्येक ऑब्जेक्ट प्रतिनिधि प्रतिनिधि हैं।ये प्रतिनिधि विधियां आग लगती हैं, जब विशेष ऑब्जेक्ट उपयोगकर्ता इंटरैक्शन और प्रोग्राम फ्लो चक्र में भाग लेते हैं।

बस कहा गया है: प्रतिनिधिमंडल वस्तुओं के बीच मजबूत परस्पर निर्भरता पैदा किए बिना एक दूसरे के साथ बातचीत करने की अनुमति देने का एक तरीका है।

1

एक प्रतिनिधि उपयोगकर्ता के टैपिंग कार्यों को कैप्चर करता है और उपयोगकर्ता टैपिंग एक्शन के अनुसार विशेष कार्य करता है।

0

प्रतिनिधि वस्तु के उदाहरण के अलावा कुछ भी नहीं है जिसे हम उस ऑब्जेक्ट्स की तरफ से विधियों को कॉल कर सकते हैं। और उस ऑब्जेक्ट्स के rumtime में विधियों को बनाने में भी मदद करता है।

3

कृपया! आईओएस में प्रतिनिधि कैसे काम करता है यह समझने के लिए चरणबद्ध ट्यूटोरियल द्वारा सरल चरण नीचे देखें।

Delegate in iOS

मैं दो ViewControllers

  1. FirstViewController प्रतिनिधि को लागू (जो डेटा प्रदान करता है) (एक से दूसरे में डेटा भेजने के लिए) बनाया है।
  2. द्वितीय दृश्य नियंत्रक प्रतिनिधि को घोषित करता है (जो डेटा प्राप्त करेगा)।

यहां नमूना कोड आपकी मदद कर सकता है।

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।मीटर


#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

हैलो आरडीसी, यह कोड काम नहीं कर रहा है, क्या आप कृपया अपने अंत में प्रयास कर सकते हैं। –

2

मुझे लगता है कि इन सभी प्रश्नों के उत्तर भावना का एक बहुत बनाने के एक बार आप प्रतिनिधियों को समझते हैं। व्यक्तिगत रूप से मैं सी/सी ++ की भूमि से और उस प्रक्रियात्मक भाषाओं जैसे कि फोरट्रान इत्यादि से आया था, इसलिए यहां मेरा 2 मिनट सी ++ प्रतिमान में समान अनुरूपता खोजने पर है।

अगर मैं एक सी ++/जावा प्रोग्रामर के प्रतिनिधियों की व्याख्या करने के लिए गए थे मैं कहूंगा कि

प्रतिनिधियों क्या हैं? ये किसी अन्य वर्ग के भीतर कक्षाओं के लिए स्थिर संकेतक हैं। एक बार जब आप एक पॉइंटर असाइन करते हैं, तो आप उस वर्ग में फ़ंक्शंस/विधियों को कॉल कर सकते हैं। इसलिए आपकी कक्षा के कुछ कार्य "प्रतिनिधि" (सी ++ दुनिया में - एक क्लास ऑब्जेक्ट पॉइंटर द्वारा पॉइंटर) में किसी अन्य वर्ग में हैं।

प्रोटोकॉल क्या हैं? संकल्पनात्मक रूप से यह उस वर्ग के शीर्षलेख फ़ाइल के समान उद्देश्य के रूप में कार्य करता है जिसे आप एक प्रतिनिधि वर्ग के रूप में निर्दिष्ट कर रहे हैं। एक प्रोटोकॉल कक्षा को एक प्रतिनिधि के रूप में सेट करने वाले वर्ग में कौन से तरीकों को लागू करने की आवश्यकता है, इसे परिभाषित करने का एक स्पष्ट तरीका है।

मैं सी ++ में कुछ कैसे कर सकता हूं? यदि आपने सी ++ में ऐसा करने की कोशिश की है, तो आप क्लास परिभाषा में पॉइंटर्स को कक्षाओं (ऑब्जेक्ट्स) में परिभाषित करके और फिर उन्हें अन्य कक्षाओं में तारों से परिभाषित करेंगे जो आपके बेस क्लास के प्रतिनिधियों के रूप में अतिरिक्त कार्य प्रदान करेंगे। लेकिन इस तारों को कोड के भीतर रखा जाना चाहिए और बेकार और त्रुटि प्रवण होगा। उद्देश्य सी मानता है कि प्रोग्रामर इस अनुशासन को बनाए रखने के लिए सबसे अच्छे नहीं हैं और एक स्वच्छ कार्यान्वयन को लागू करने के लिए संकलक प्रतिबंध प्रदान करते हैं।

3

मैं साधारण प्रोग्राम के माध्यम से यह विस्तृत करने के

दो वर्गों

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

कोशिश

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

व्याख्या :::

  1. मुख्य विधि से जब initWithStudent:student निष्पादित करेंगे

    1.1 शिक्षक की वस्तु की संपत्ति 'छात्र' छात्र वस्तु के साथ सौंपा जाएगा।

    1,2 self.student.delegate = self

    means student object's delegate will points to teacher object 
    
  2. मुख्य विधि से जब [student studentInfo]

    2 बुलाया जाएगा।1 [self.delegate respondToSelector:@selector(teacherName)] यहां प्रतिनिधि पहले ही शिक्षक ऑब्जेक्ट को इंगित करता है ताकि यह 'शिक्षक नाम' उदाहरण विधि का आह्वान कर सके।

    2.2 तो [self.delegate performSelector:@selector(teacherName)] आसानी से निष्पादित करेगा।

ऐसा लगता है कि शिक्षक ऑब्जेक्ट छात्र ऑब्जेक्ट को अपनी खुद की विधि कहने के लिए प्रतिनिधि निर्दिष्ट करता है।

यह एक सापेक्ष विचार है, जहां हम देखते हैं कि छात्र ऑब्जेक्ट 'शिक्षक नाम' विधि कहा जाता है लेकिन यह मूल रूप से शिक्षक वस्तु द्वारा किया जाता है।

संबंधित मुद्दे