2010-12-27 6 views
7

मेरे उद्देश्य-सी वर्ग को शुरू करने के लिए मेरे पास दो अलग-अलग विधियां हैं I एक डिफ़ॉल्ट है, और एक कॉन्फ़िगरेशन पैरामीटर लेता है। अब, जब मैं उद्देश्य-सी की बात करता हूं, तो मैं बहुत हरा हूं, लेकिन मैंने इन तरीकों को लागू किया है और मैं सोच रहा हूं कि अगर मैंने इसे शुरू करने के तरीके से शुरुआतीकरण को संभालने के लिए बेहतर (अधिक सही/अच्छी शैली में) तरीका है । मतलब, क्या मैंने इन प्रारंभिक कार्यों को मानकों और अच्छी शैली के अनुसार लिखा था? यह selfPtr के अस्तित्व की जांच करने का अधिकार नहीं है और उसके बाद उस पर आधारित है।उद्देश्य-सी डिफ़ॉल्ट init विधि?

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

#import <Cocoa/Cocoa.h> 

// class for raising events and parsing returned directives 

@interface awesome : NSObject { 
// silence is golden. Actually properties are golden. Hence this emptiness. 
} 

// properties 
@property (retain) SBJsonParser* parser; 
@property (retain) NSString* eventDomain; 
@property (retain) NSString* appid 

// constructors 
-(id) init; 
-(id) initWithAppId:(id) input; 

// destructor 
-(void) dealloc; 


@end 

#import "awesome.h" 
#import "JSON.h" 


@implementation awesome 



- (id) init { 
if (self = [super init]) { 
    // if init is called directly, just pass nil to AppId contructor variant 
    id selfPtr = [self initWithAppId:nil]; 
} 

if (selfPtr) { 
    return selfPtr; 
} else { 
    return self; 
} 
} 

- (id) initWithAppId:(id) input { 
if (self = [super init]) { 
    if (input = nil) { 
    input = [[NSString alloc] initWithString:@"a369x123"]; 
    } 
    [self setAppid:input]; 
    [self setEventDomain:[[NSString alloc] initWithString:@"desktop"]]; 
} 
return self; 
} 

// property synthesis 
@synthesize parser; 
@synthesize appid; 
@synthesize eventDomain; 

// destructor 
- (void) dealloc { 
self.parser = nil; 
self.appid = nil; 
self.eventDomain = nil; 
[super dealloc]; 
} 

@end 

धन्यवाद!

+1

एक विशेष समस्या जो मैं देखता हूं वह यह है कि यदि 'init' का उपयोग किया जाता है, तो' [सुपर init] 'को दो बार बुलाया जाता है। – dreamlax

+2

आप 'eventDomain' प्रॉपर्टी को भी लीक कर रहे हैं, क्योंकि आप +1 स्वामित्व गिनती के साथ ऑब्जेक्ट बनाते हैं, और इसे एक विधि को देते हैं जो स्वामित्व गिनती को +2 तक बढ़ा देता है, तो आपकी डेलोक विधि केवल इसे +1 पर वापस लाती है।यह आपके 'भयानक' ऑब्जेक्ट के सापेक्ष 0 होना चाहिए। – dreamlax

+0

इसके अलावा, 'कोको/कोको.h' शामिल है मैक ओएस एक्स के लिए, आईओएस के लिए नहीं। – jer

उत्तर

14

एक प्रारंभकर्ता बस कुछ डिफ़ॉल्ट पैरामीटर के साथ और अधिक जटिल प्रारंभकर्ता करता है, यह इस तरह के रूप में बुलाने:

-(id)init { 
    return [self initWithAppID:nil]; 
} 

-(id)initWithAppID:(id)input { 
    if (self = [super init]) { 
    /* perform your post-initialization logic here */ 
    } 
    return self; 
} 
आमतौर पर

आप "प्रारंभिक प्रारंभकर्ता" प्रारंभकर्ताओं में से एक को बनाने का प्रयास करें, जिसका अर्थ यह है कि यह हमेशा होता है। इस मामले में -initWithAppID: है।

0

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

+ (awesome*)awesome; 
+ (awesome*)awesomeWithAppId:(id)foo; 

और उदाहरण के लिए +awesome के लिए अपने कार्यान्वयन में, इस तरह यह लिखना:

+ (awesome*)awesome 
{ 
    return [[[awesome alloc] initWithAppId:@"a369x123"] autorelease]; 
} 

और इसी तरह, अपने awesomeWithAppId: कुछ इस तरह में

उदाहरण के लिए, एक वर्ग प्रणाली की घोषणा:

+ (awesome*)awesomeWithAppId:(id)foo 
{ 
    return [[[awesome alloc] initWithAppId:foo] autorelease]; 
} 

फिर फिर, यह हो सकता है मुझे।

0

default हो जाएगा जो भी आप कॉल करना चुनते हैं, तो

[awesome alloc] init]; 
[awesome alloc] initWithAppId:ID]; 
1

आपकी init विधि को पसंदीदा कार्यान्वयन, initWithAppId: को सुपर कार्यान्वयन के बजाय कॉल करना चाहिए। फिर initWithAppId सुपर कार्यान्वयन को कॉल करता है, जैसा कि करता है। इसके अलावा, initWithAppId में :, यदि आपके पास (इनपुट = शून्य) है, जो हमेशा इनपुट करने के लिए इनपुट सेट करेगा और YES का मूल्यांकन करेगा। यहां उचित कार्यान्वयन हैं।

- (id)init { 
    return [self initWithAppId:nil]; 
} 
- (id)initWithAppId:(id)input { 
    if((self = [super init])) { 
     if(input == nil) input = @"a369x123"; 
     self.appid = input; 
     self.eventDomain = @"desktop"; 
    } 
    return self; 
}