2010-01-08 10 views
15

मेरे पास एक उद्देश्य-सी कक्षा के भीतर एकाधिक प्रारंभकर्ता बनाने के बारे में एक साधारण सवाल है। असल में मेरे पास एक कक्षा है जो मेरे डेटाबेस (उपयोगकर्ताओं) में एक पंक्ति का प्रतिनिधित्व करती है। मेरे पास वर्तमान में एक प्रारंभकर्ता है जो उपयोगकर्ता आईडीआईडी ​​(जो डाटाबेस के भीतर प्राथमिक कुंजी भी है) के आधार पर कक्षा शुरू करता है, जब उपयोगकर्ता आईडी को पारित किया जाता है तो कक्षा उन्हें एक webservice से कनेक्ट करेगी परिणाम को पार्स करेगी और इसी पंक्ति में प्रारंभ की गई वस्तु को वापस कर देगी डेटाबेस मेंउद्देश्य-सी एकाधिक प्रारंभिक

इस डेटाबेस के भीतर कई अद्वितीय फ़ील्ड (उपयोगकर्ता नाम और ईमेलड्रेस) हैं, मैं भी इन मानों के आधार पर अपनी वस्तु को आरंभ करने में सक्षम होना चाहूंगा। लेकिन मुझे यकीन है कि एक से अधिक प्रारंभिक कैसे हो सकते हैं, मैंने जो कुछ भी पढ़ा है, वह कहता है कि जब तक प्रत्येक नामित प्रारंभिक कॉलर को कॉल करता है, तब तक मैं कई प्रारंभिक होने के लिए स्वतंत्र हूं। अगर कोई मेरी मदद कर सकता है, तो यह बहुत अच्छा होगा।

मेरे initialiser कोड इस प्रकार है:

- (id) initWithUserID:(NSInteger) candidate { 
    self = [super init]; 
    if(self) { 
     // Load User Data Here 
     NSString *soapMessage = [NSString stringWithFormat: 
           @"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" 
           "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" 
           "<soap:Body>\n" 
           "<GetByUserID xmlns=\"http://tempuri.org/\">\n" 
           "<UserID>%d</UserID>\n" 
           "</GetByUserID>\n" 
           "</soap:Body>\n" 
           "</soap:Envelope>\n", candidate 
           ]; 
     NSLog(@"%@",soapMessage); 

     // Build Our Request 
     NSURL *url = [NSURL URLWithString:@"http://photoswapper.mick-walker.co.uk/UsersService.asmx"]; 
     NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url]; 
     NSString *msgLength = [NSString stringWithFormat:@"%d", [soapMessage length]]; 

     [theRequest addValue: @"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"]; 
     [theRequest addValue: @"http://tempuri.org/GetByUserID" forHTTPHeaderField:@"SOAPAction"]; 
     [theRequest addValue: msgLength forHTTPHeaderField:@"Content-Length"]; 
     [theRequest setHTTPMethod:@"POST"]; 
     [theRequest setHTTPBody: [soapMessage dataUsingEncoding:NSUTF8StringEncoding]]; 

     NSError *WSerror; 
     NSURLResponse *WSresponse; 

     webData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&WSresponse error:&WSerror]; 

     xmlParser = [[NSXMLParser alloc] initWithData: webData]; 
     [xmlParser setDelegate: self]; 
     [xmlParser setShouldResolveExternalEntities: YES]; 
     [xmlParser parse]; 
    } 
    return self; 
} 

लॉरेंट की टिप्पणी से के बाद, मैं अपने खुद के समाधान को लागू करने की कोशिश की है, अगर आप इस समाधान के साथ किसी भी स्पष्ट पकड़ लिया है की मुझे सूचित कर सकता है मैं आभारी होंगे:

मुझे पूरा यकीन नहीं है कि मैं समझता हूं कि आप अर्थ हैं, मैंने अपना स्वयं का समाधान लागू करने का प्रयास किया है।

- (id) init { 
    self = [super init]; 
    if(self){ 
     // For simplicity I am going to assume that the 3 possible 
     // initialation vectors are mutually exclusive. 
     // i.e if userName is used, then userID and emailAddress 
     // will always be nil 
     if(self.userName != nil){ 
      // Initialise object based on username 
     } 
     if(self.emailAddress != nil){ 
      // Initialise object based on emailAddress 
     } 
     if(self.userID != 0){ // UserID is an NSInteger Type 
      // Initialise object based on userID 
     } 
    } 
    return self; 
} 
- (id) initWithUserID:(NSInteger) candidate { 
    self.userID = candidate; 
    return [self init]; 
} 
- (id) initWithEmailAddress:(NSString *) candidate { 
    self.emailAddress = candidate; 
    return [self init]; 
} 
- (id) initWithUserName:(NSString *) candidate { 
    self.userName = candidate; 
    return [self init]; 
} 

सादर

+2

चेतावनी - संभवतः आवेदन विफलता: आप स्वयं .userID या इसी तरह सेट करने से पहले नामित प्रारंभकर्ता का उपयोग करके स्वयं को प्रारंभ करने की आवश्यकता है। ऐसा इसलिए है क्योंकि 1) ऑब्जेक्ट मेमोरी को [सुपर इनिट] में [सुपर इनिट] में कॉल करके एक नए स्थान पर फिर से स्थानांतरित किया जा सकता है, अपना प्रारंभिक चर खोना और 2) उपयोगकर्ता आईडी को कॉल [सेल्फ इनिट] पर ओवरराइट किया जा सकता है। ऐसा करें: अगर (स्वयं = [स्वयं init]) {self.userID = उम्मीदवार} स्वयं लौटें; –

उत्तर

16

नामित प्रारंभकर्ता की परिभाषा here है: मैं आभारी अगर तुम दे सकता है मुझे पता है आप क्या सोचते हैं होगा। यह सुनिश्चित करने के लिए एक मजबूत आवश्यकता है कि आपके उदाहरण जो भी प्रारंभकर्ता आप उपयोग करते हैं, वे सुसंगत हैं। पूर्ण संदर्भ के लिए, Objective-C Programming Guide देखें: प्रारंभकर्ता कार्यान्वयन अच्छी तरह से प्रलेखित है।

संपादित करें 2: फिक्स टाइपो @NSResponder

संपादित करें द्वारा रिपोर्ट:

मैं सदस्य सेट करने के बाद init बुला लगता है कि विश्वसनीय नहीं है। सदस्यों के पास अजीब मूल्य हो सकते हैं जो प्रारंभिकरण के लिए परीक्षण विफल हो जाएंगे।

ऐसा करने का एक बेहतर तरीका है "init" विधि को पहले कॉल करना (जो सदस्यों के लिए डिफ़ॉल्ट मान निर्धारित करेगा) और फिर सदस्य को सेट करने के लिए। इस तरह, आप अपने सभी initializers के लिए एक ही कोड संरचना है:

- (id) init { 
    self = [super init]; 
    if(self){ 
     self.userID = 0; 
     self.userName = nil; 
     self.emailAddress = nil; 
    } 
    return self; 
} 

- (id) initWithUserID:(NSInteger) candidate { 
    self = [self init]; 
    if(self){ 
     self.userID = candidate; 
    } 
    return self; 
} 
+0

मैंने अपनी मूल पोस्ट संपादित की है, क्या आप मुझे बता सकते हैं कि आप इस समाधान के बारे में क्या सोचते हैं। बहुत बहुत धन्यवाद मिक –

+0

एक अन्य प्रस्ताव के लिए मेरा संपादन देखें। –

+0

क्या मैं एक प्रश्न पूछ सकता हूं?कक्षा में नामित प्रारंभिक क्या है? यदि कक्षा उपclassed है, init नामित प्रारंभिक नहीं हो सकता है जिसे उपclass के प्रारंभकर्ता द्वारा बुलाया जाना चाहिए क्योंकि उस समय उपयोगकर्ता आईडी, ईमेल एड्रेस, और उपयोगकर्ता नाम को अभी तक एक औसत मूल्य असाइन नहीं किया गया है। – yehnan

7

तरह से मैं बात इस तरह का करते है नामित प्रारंभकर्ता विधि यह है कि ज्यादातर पैरामीटर लेता है, और सरल initializers होने के लिए बस अधिक विस्तृत-इनिट संदेश भेजें। उदाहरण के लिए:

// simple initializer 
- (id) init 
    { 
    return [self initWithWidth: 1.0]; 
    } 

    // not so simple initializer 
- (id) initWithWidth:(float) aWidth 
    { 
    return [self initWithWidth:aWidth andColor:nil]; 
    } 

    // designated initializer. This is the one that subclasses should override. 
- (id) initWithWidth: (float) aWidth andColor: (NSColor *) aColor 
    { 
    if (self = [super init]) 
    { 
    self.width = aWidth; 
    self.color = aColor ? aColor : [[self class] defaultColor]; 
    } 
    return self; 
    } 
संबंधित मुद्दे