2009-06-22 5 views
7

उद्देश्य-सी कक्षा के कार्यान्वयन ब्लॉक (@ कार्यान्वयन ... @end) के अंदर या बाहर घोषित सी फ़ंक्शन (स्थिर या नहीं) के बीच क्या अंतर है?ओब्जे-सी: सी फ़ंक्शंस @ कार्यान्वयन ब्लॉक के अंदर या बाहर घोषित किया गया है, क्या अंतर है?

इस विशेष रूप से सच ?:

आप सीधे वस्तु के अंदर निकालना पड़ सकता है, तो आप अपने वर्ग के @implementation ब्लॉक के अंदर इस समारोह रख सकते हैं, और फिर आप के साथ उदाहरण चर का उपयोग कर सकते है सी तीर ऑपरेटर। लेकिन यह शरारती है, इसलिए अपनी शुद्धता की शुद्धता को संरक्षित करने के लिए आपको अपनी वस्तु पर विधि कॉल का उपयोग करना चाहिए। उपदेश का अंत

@implementation OblateSphereoid 

void drawEggThunk (DrawingContext *context, Rect areaToDraw, void *userData) 
{ 
BWOblateSphereoid *dealie = (BWOblateSphereoid *)userData; 
dealie->_frognatz = [NSColor plaidColor]; 
// and more stuff. 
} // drawEggThunk 

... 
@end // OblateSphereoid 

मैं इस तरह से काम करता है (एक ही कक्षा में घोषित) के भीतर मेरी कक्षा का उदाहरण चर का उपयोग कर सकते: यहाँ बुराई है?

+0

एक दिलचस्प सवाल होने के लिए उपरोक्त (हालांकि शायद बहुत बुरा अभ्यास) जिज्ञासा से बाहर, आप केवल अपनी कक्षा के भीतर से drawEggThunk को कॉल कर सकते हैं? –

+0

मैं नहीं कर सकता, फ़ंक्शन एक सी सबसिस्टम से कॉल किया गया एक कॉलबैक फ़ंक्शन है, क्योंकि आप देख सकते हैं कि मैं कॉलबैक सेट होने पर स्वयं के संदर्भ को पास करने के लिए * userData का उपयोग करता हूं। – jlpiedrahita

उत्तर

2

हालांकि यह कानूनी है, मुझे समझ में नहीं आता कि आपके द्वारा वर्णित मामले में इसकी आवश्यकता क्यों है (और यह एक बदसूरत समाधान है)। आप क्यों नहीं बस फोन नहीं कर सकते हैं:

[dealie setFrognatz:[NSColor plaidColor]]; 

आप आमतौर पर एक -setFrognatz: प्रदान नहीं करते हैं, बस इसे मीटर के अंदर यह घोषणा करके एक निजी विधि बनाने, लेकिन इस समारोह परिभाषा ऊपर। (यह वास्तव में अगर यह इस मामले में @implementation ब्लॉक में है कोई फर्क नहीं पड़ता।)

@interface BWOblateSphereoid() 
- (void)setFrognatz:(NSColor *)acolor 
@end 

@implementation OblateSphereoid 

void drawEggThunk (DrawingContext *context, Rect areaToDraw, void *userData) 
{ 
    BWOblateSphereoid *dealie = (BWOblateSphereoid *)userData; 
    [dealie setFrognatz:[NSColor plaidColor]]; 
    // and more stuff. 
} // drawEggThunk 

... 
@end // OblateSphereoid 

में कुछ स्थानों पर जहां -> अंकन सहायक हो सकता है कर रहे हैं। सबसे महत्वपूर्ण -copyWithZone: लागू करने में है जहां यह absolutely required हो सकता है (एक आवश्यकता जो वास्तव में जोर देती है कि मुझे किसी भी ओबीजेसी कोड से नफरत है जो NSCopyObject() करता है जैसे कच्चे मेमोरी के साथ खेलता है)। लेकिन मैं ज्यादातर मामलों में -> के खिलाफ सलाह देता हूं क्योंकि मैं हमेशा एक्सेसर्स की सलाह देता हूं। यहां तक ​​कि उस मामले में जहां आपको एक सी फ़ंक्शन (-> का एक और सामान्य उपयोग) के संदर्भ में एक ivar पास करने की आवश्यकता है, मैं अस्थायी उपयोग करना पसंद करता हूं और फिर इसे बाद में असाइन करता हूं।

मैं ObjC में एक बग होने के लिए तथ्य यह है कि ivars डिफ़ॉल्ट रूप से @private नहीं हैं पर विचार .... मैं हर @interface ब्लॉक के शीर्ष पर @private रख दिया और कई बुरा कीड़े कि जिस तरह से परहेज किया।

बीटीडब्ल्यू, लिखित के रूप में आपका समाधान NSColor लीक हो सकता है। शायद यह है, शायद यह नहीं है, लेकिन एक सहायक निश्चित होगा।

+0

"निजी" विधि अंतर्निहित समस्या का उत्तर है (बिना ब्रेक encapsulation के कार्यों के भीतर प्रवेश ivars) :) लेकिन ... @impementation के अंदर और बाहर कार्यों के बीच कुछ अंतर है? – jlpiedrahita

+0

वैसे, objc ivars डिफ़ॉल्ट रूप से @ संरक्षित हैं, यह सही दायरा है: वर्ग स्वयं और उप-वर्गों के लिए दृश्यमान, और बाकी सभी के लिए छिपा हुआ है। – jlpiedrahita

+0

अंदर और बाहर @ कार्यान्वयन के बीच कोई अंतर नहीं है। –

2

यह आपके @ कार्यान्वयन के अंदर ठीक काम करेगा। मैं आपको एक सामान्य विधि बनाने की सलाह दूंगा, लेकिन यह काम करता है।

यदि आप इसे अपने कार्यान्वयन से बाहर रखते हैं, तो आपको यह चेतावनी मिलती है: चेतावनी: इंस्टेंस वैरिएबल '@ संरक्षित है; भविष्य में यह एक कठिन त्रुटि होगी। आप शीर्षक में अपने इवर से पहले एक @public डाल ... इसलिए तरह से इस त्रुटि से बचने कर सकते हैं:

@public 
int myInt; 

आप एक सी (सूचक) की तरह चर का उपयोग करने के Struct जहाँ भी वस्तु बिना किसी चेतावनी के लिए प्रकट होता है की अनुमति देता है कि।

तो यह करने योग्य, हालांकि अनुशंसित नहीं है !!!

+0

मुझे लगता है कि यह भी एक बुरा अभ्यास हो सकता है, लेकिन मैं इवान को सिर्फ encapsulation के पक्ष में जनता के रूप में बेनकाब नहीं करना चाहता, लेकिन मेरे सी कॉलबैक फ़ंक्शन उदाहरण इवर को देखने में सक्षम होना चाहिए। – jlpiedrahita

+0

तब आपको वह करना चाहिए जो आपको करना है ... आपको अपने सभी आईवर्स को सार्वजनिक रूप से घोषित करने की आवश्यकता नहीं है, आप मिश्रण और मिलान कर सकते हैं। – micmoo

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

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