2009-11-10 17 views
40

यदि मैं कोई कस्टम इनिट बनाता हूं तो किसी ऑब्जेक्ट के लिए क्या मैं अनिवार्य रूप से उस कोड को शामिल करता हूं जिसे मैं जोड़ना चाहता हूं, क्या मुझे इनिट को ओवरराइड करना चाहिए?एक कस्टम init के साथ जोड़ना?

-(id) init { 
    self = [super init]; 
    if (self) { 
     NSLog(@"_init: %@", self); 
    } 
    return(self); 
} 

उदा।

-(id) initWithX:(int) inPosX andY:(int) inPosY { 
    self = [super init]; 
    if(self) { 
     NSLog(@"_init: %@", self); 
     posX = inPosX; 
     posY = inPosY; 
    } 
    return(self); 
} 

गैरी

उत्तर

81

आप एक नामित प्रारंभकर्ता बना सकते हैं जो प्रारंभिकरण में उपलब्ध सभी पैरामीटर को स्वीकार करता है।

फिर आप उचित पैरामीटर के साथ अपने अन्य -(id)init अपने नामित प्रारंभकर्ता से कॉल करें।

केवल नामित प्रारंभकर्ता सुपर क्लास [super init] आरंभ करेगा।

उदाहरण:

- (id)init 
{ 
    return [self initWithX:defaultX andY:defaultY]; 
} 

- (id)initWithPosition:(NSPoint)position 
{ 
    return [self initWithX:position.x andY:position.y]; 
} 


- (id)initWithX:(int)inPosX andY:(int)inPosY 
{ 
    self = [super init]; 
    if(self) { 
     NSLog(@"_init: %@", self); 
     posX = inPosX; 
     posY = inPosY; 
    } 
    return self; 
} 

नामित प्रारंभकर्ता -(id)initWithX:andY: है और आप अन्य initializers से यह कहते हैं।

यदि आप इस कक्षा को विस्तारित करना चाहते हैं तो आप उपनाम से अपना नामित प्रारंभकर्ता कॉल करें।

+0

लाइन 'रिटर्न (स्वयं) के लिए' स्वयं 'के आसपास कोष्ठक का कारण क्या है; '? क्या यह 'BOOL' मान वापस करता है? – musubi

+0

'वापसी (स्वयं)' एक टाइपो था ... – stefanB

6

हाँ, वह वास्तव में कैसे मैं यह कर रहा है।

self = [super init]; 
if(self) { 
+2

चेतावनी सक्षम शिकायत के साथ जीसीसी , क्योंकि 'if'' में 'if' अधिक जानबूझकर दुर्घटना से अधिक उपयोग किया जाता है। मैं इसे ओपी के बारे में लिखूंगा, लेकिन चेतावनी को चुप करने के लिए, 'अगर ((self = [super init]))' (अतिरिक्त कोष्ठक नोट करें) करेंगे। – ephemient

+0

तो आप इस प्रारंभिक जटिल कक्षा के लिए आपके पास 150 विभिन्न प्रारंभिक विधियों के लिए एक ही प्रारंभिक कोड की प्रतिलिपि बनाना चाहते हैं? – stefanB

+0

नहीं, स्टीफन, मैं आमतौर पर जो करता हूं वह करता हूं।जिस तरह से मैंने अपना उदाहरण पढ़ा, वह init को बदलना था: initWithX: andY:, initWithX जोड़ने के बजाय: और वाई:, इसलिए इस पहलू में नहीं आया। लेकिन यह एक महान बात है, खुशी है कि आपने इसे बनाया! टिप्पणी के लिए धन्यवाद, ephemient। मैंने हमेशा सोचा था कि क्यों कोड उदाहरण अक्सर ऐसा करते थे, क्योंकि यह इसके बिना ठीक बनाता है। स्पष्ट रूप से मेरे एक्सकोड में सभी चेतावनियों को सक्षम नहीं किया गया था। तुमने मुझे प्रेरित किया है! –

9

मैं एक मुख्य प्रारंभकर्ता है कि काम के सबसे संभालती बनाने का सुझाव चाहते हैं: के रूप में करने का विरोध किया

if (self = [super init]) { 

: एक मामूली बदलाव कोड की एक पंक्ति को काट देगा। फिर आप किसी भी अन्य प्रारंभकर्ताओं को बना सकते हैं जो सभी इस मुख्य को कॉल करते हैं। इसका लाभ यह है कि यदि आप प्रारंभिक प्रक्रिया को बदलना चाहते हैं, तो आपको केवल एक स्थान (सामान्य रूप से) बदलना होगा। यह ऐसा दिखाई दे सकता है:

-(id) initWithX:(float)x { 
    if (self = [super init]) { 
     /* do most of initialization */ 
     self.xVal = x; 
    } 
    return(self); 
} 

-(id) init { 
    return [self initWithX:0.0f]; 
} 

इस उदाहरण में initWithX: हमारा मुख्य प्रारंभकर्ता है। अन्य प्रारंभकर्ता (init) बस initWithX को कॉल करता है: डिफ़ॉल्ट मान के साथ (इस मामले में 0)।

+0

आपकी 'init' को [self initWithX: 0.0f] का परिणाम वापस करना चाहिए। –

+0

हाँ, इसे याद किया। फिक्स्ड। धन्यवाद। – dbachrach

2

कभी-कभी, आप कुछ शुरुआतीकरण कोड का पुन: उपयोग करना चाहते हैं और विशिष्ट प्रारंभकर्ताओं के लिए केवल व्यवहार को संशोधित करना चाहते हैं। इस मामले में, मैं निम्न कार्य करें:


- (id) init 
{ 
    self = [super init]; 
    if (!self) return nil; 

    // These values are always initialised this way 
    ivar1 = 10; 
    ivar2 = @"HellO"; 
    ivar3 = [[NSMutableArray alloc] initWithCapacity:10]; 
    ivar4 = 22; 

    return self; 
} 

- (id) initWithIvar4:(int) aValue 
{ 
    // call -init on self, which will call -init on super for us, and set 
    // up ivar1, ivar2, ivar3, and ivar4. 
    self = [self init]; 
    if (!self) return nil; 

    // Change ivar4 from the default 22 to whatever aValue is. 
    ivar4 = aValue; 

    return self; 
} 

+0

यह एक और विकल्प है, लेकिन अगर आप केवल इनिट को कॉल करते हैं तो आप ivar4 को प्रारंभ नहीं कर रहे हैं, और आपको याद रखना होगा कि उस विशिष्ट प्रारंभकर्ता में आप नहीं कुछ चर शुरू करें लेकिन अन्य प्रारंभकर्ता उन्हें प्रारंभ करते हैं ... मुझे लगता है कि थोड़ा सा त्रुटि मुझे लगता है ... – stefanB

+0

क्षमा करें, मैंने एक बहुत ही सभ्य उदाहरण प्रदान नहीं किया है। यह कोड स्वीकार करने के लिए डिज़ाइन किया गया था कि 'ivar4' का 0 का डिफ़ॉल्ट मान है, जब तक कि विशेष रूप से' initWithIvar4: 'के साथ सेट न हो। आप 'ivar4' को आसानी से' - [self init] 'में भी सेट कर सकते हैं, लेकिन आप सही हैं, आप आसानी से कुछ चर के साथ समाप्त हो सकते हैं और कुछ नहीं, और आसानी से पता लगाने में सक्षम नहीं हैं कि कुछ चर सेट किए गए हैं । – dreamlax

+0

इसे संपादित करने के लिए संपादित कोड अधिक समझदार है। – dreamlax

4

modern Objective-C के लिए ...

UDFile.h

#import <Foundation/Foundation.h> 

@interface UDFile : NSObject 

@property (nonatomic, strong) NSString *name; 

- (instancetype)initWithName:(NSString *)name NS_DESIGNATED_INITIALIZER; 

@end 

UDFile.m

#import "UDFile.h" 

@implementation UDFile 

- (instancetype)initWithName:(NSString *)name { 
    self = [super init]; 
    if (self) { 
     _name = [name copy]; 
    } 
    return self; 
} 

- (instancetype)init { 
    return [self initWithPathname:@""]; 
} 
संबंधित मुद्दे