2012-02-09 23 views
12

मुझे यकीन है कि कितना उपयोग इस सवाल यह है कि नहीं कर रहा हूँ, लेकिन यह मेरे लिए दिलचस्प लगता है ...डॉट वाक्य रचना बनाम गेटर के साथ विधि वाक्य रचना =

मैंने सोचा था कि संपत्ति का उपयोग कर/संश्लेषण बयान मुझे के बराबर था गेटर बनाने/सेटर। इसलिए

// .h 
@property (nonatomic) BOOL on; 

// .m 
@synthesize on = _on; 

// In my mind synthesizes the following methods 

// - (BOOL)on; 
// - (void)setOn:(BOOL)on; 

लेकिन अगर मैं निम्नलिखित करने के लिए घोषणाओं को बदलें:

       v 
@property (nonatomic, getter=isOn) BOOL on; 

@synthesize on = _on; 

// In my mind synthesizes the following 

// - (BOOL)isOn; 
// - (void)setOn:(BOOL)on; 

तो ऊपर दिए गए मैं इतना गेटर ओवरराइड मैं जानता हूँ कि जब यह कहा जाता है:

- (BOOL)isOn; 
{ 
    NSLog(@"I was called"); 
    return _on; 
} 

अब बुला उदाहरण पर निम्नलिखित (myClass) परिणाम:

NSLog(@"%d", [myClass isOn]); 

//=> 2012-02-09 22:18:04.818 Untitled[1569:707] I was called 
//=> 2012-02-09 22:18:04.820 Untitled[1569:707] 1 

NSLog(@"%d", myClass.isOn); 

//=> 2012-02-09 22:18:24.859 Untitled[1599:707] I was called 
//=> 2012-02-09 22:18:24.861 Untitled[1599:707] 1 

NSLog(@"%d", myClass.on);   // This is the one I didn't expect to work 

//=> 2012-02-09 22:18:55.568 Untitled[1629:707] I was called 
//=> 2012-02-09 22:18:55.570 Untitled[1629:707] 1 

मैं हमेशा मान लिया था कि यह पूरी तरह से रूप में डॉट वाक्य रचना के साथ गेटर/सेटर उपयोग करने के लिए मान्य था अगर मैं इस अर्थ में एक संपत्ति का उपयोग कर रहा था

myClass.isOn; 
myClass.on = on; 

एक और question से यह सुझाव दिया गया कि जब डॉट का उपयोग कर वाक्य रचना मैं इस तरह संपत्ति नाम का उपयोग करना चाहिए:

myClass.on // Correct 
myClass.isOn // Incorrect 

इस काम करता है हालांकि यह थोड़ा कम तार्किक प्रतीत क्योंकि मैं जानता हूँ कि कोई अंतर्निहित विधि - (BOOL)on यह बजाय - (BOOL)isOn

करने के लिए मैप किया गया है है वहाँ

मेरे सवालों का (उत्तरार्द्ध उदाहरण का उपयोग) कर रहे हैं

  • यह एक बग है या myClass.on वास्तव में चुपचाप - (BOOL)isOn
  • कॉल करने के लिए शब्दार्थ बोल रहा राज्य लागू नहीं व्यवहार तक पहुँचने हूँ तो मेरे के वर्तमान उपयोग है बदला जाना चाहिए डॉट वाक्यविन्यास सही है? (myClass.isOn जैसे)

अद्यतन

हालांकि कोई भी स्पष्ट रूप से यह कहा गया है मैं तर्क है कि .isOn का उपयोग कर बुरा प्रपत्र तथ्य की वजह से भले ही है कि हुड के नीचे एक ही विधि कहा जाता है, शब्दार्थ है isOn एक प्रश्न पूछ रहा है, जो राज्य के बजाय अधिक व्यवहार है।

हालांकि मैं अभी भी जहां "जादू" तारों से चला जाता है पर कि [myClass isOn]


अद्यतन 2

में myClass.on के लिए कॉल बदल जाता है डॉक्स के आसपास कुछ देखने के बाद पर स्पष्ट नहीं कर रहा हूँ और मैं पर इस खंड पाया Declared Properties।निम्नलिखित कोड का उपयोग कर सकते हैं मैं एक वर्ग 'गुण का निरीक्षण:

id MyClass = objc_getClass("MyClass"); 
unsigned int outCount, i; 

objc_property_t *properties = class_copyPropertyList(MyClass, &outCount); 
for (i = 0; i < outCount; i++) { 
    objc_property_t property = properties[i]; 
    NSLog(@"Name: %s, attributes: %s\n", property_getName(property), property_getAttributes(property)); 
} 

//=> 2012-02-10 07:10:28.333 Untitled[934:707] Name: on, attributes: Tc,GisOn,V_on 

तो हमारे पास निम्न विशेषताओं:

  • नाम = पर
  • प्रकार = चार (टीसी)
  • गेटर = ison (GISON)
  • चर = _on (V_on)

रनटाइम पर उपलब्ध इस सारी जानकारी के साथ यह सवाल छोड़ देता है कि यह लुकअप रनटाइम पर किया गया है या कुछ उत्तरों जैसे संकलित समय का सुझाव है?

उत्तर

4

हालांकि मैं अभी भी जहां "जादू" तारों से चला जाता है पर कि [myClass ison]

, के रूप में इस प्रकार है जब एक obj संकलन तर्क निश्चित रूप से चला जाता है में myClass.on के लिए कॉल बदल जाता है पर स्पष्ट नहीं कर रहा हूँ। एक हो रही संदर्भ में नाम:

if(there is an accessible @property for name in scope) 
{ 
    if(there is a custom getter specified) 
     compile "[obj customGetter]" 
    else 
     compile "[obj name]" 
} 
else if (there is an an accessible instance method name in scope) 
    compile "[obj name]" 
else 
{ 
    compile "[obj name]" 
    warn obj may not respond to name 
} 

अन्य तरीके एक भाषा/निष्पादन वातावरण कस्टम गेटर नाम संभाल कर सकते हैं हैं, लेकिन यह देखते हुए कि Obj सी हैडर (जो सार्वजनिक है) में घोषणा डालता ऊपर एक अच्छा है अनुमान लगाएं कि कस्टम गेटर तर्क कहाँ है मेड - कॉल साइट संकलित करते समय।

+0

मुझे लगता है कि अवधारणात्मक रूप से क्या होता है मैं केवल अपने अवलोकनों के बजाय कुछ और दस्तावेज ढूंढने की कोशिश कर रहा था।कृपया मेरा अपडेट देखें, यदि यह संकलित समय या रनटाइम –

+0

@ Paul.s पर किया गया है तो ठीक है। ठीक है, मैंने एक सरल परीक्षण चलाया (दोनों प्रकारों को संकलित करें और असेंबलर को देखें) और उत्तर कम से कम वर्तमान क्लैंग द्वारा संकलित समय है संकलक। जैसा कि मैंने उपर्युक्त सुझाव दिया है, यह समझ में आता है - जानकारी हेडर में रखी गई है और कार्यान्वयन में नहीं है। मैं वास्तव में कल्पना नहीं कर सकता कि यह रनटाइम पर क्यों किया जाएगा - रिज़ॉल्यूशन के रूप में 'कस्टम गेटटर' वास्तव में किस विधि को आमंत्रित करता है, अभी भी रनटाइम पर किया जाएगा। संपत्ति के नाम के रनटाइम रिज़ॉल्यूशन के लिए रनटाइम पर कस्टम गेटर नाम उपयोगी होने के लिए आपको रनटाइम पर उस मैपिंग को बदलने का समर्थन करना होगा। – CRD

2

खैर डॉट नोटेशन के विषय में, मुझे आरोन हिलेगास (। मैक OSX, 3 एड के लिए कोको प्रोग्रामिंग) का हवाला देते हैं:

"कुल मिलाकर, मुझे लगता है कि इस भाषा के लिए एक नहीं बल्कि मूर्खतापूर्ण है क्योंकि हम पहले से ही एक था संदेश भेजने के लिए वाक्यविन्यास। "

जब आपके पास सदस्य चर हो, और इस चर के लिए आपके गेटर को तब कहा जाता है, तो .on और .isOn दो बहुत ही अलग तरह की चीजें हैं। गेटर (और शायद एक सेटर भी) का उपयोग करके आप "सूचना छिपाने" वादे का पालन करेंगे, जबकि सदस्य चर के लिए सीधे पहुंच का उपयोग करके आप नहीं करेंगे। कोको उन चीजों को लागू नहीं करेगा क्योंकि यह सम्मेलनों पर निर्भर है। यह तय करने के लिए आप पर निर्भर है कि आपके लिए कौन सा रास्ता सही है। सम्मेलन को ध्यान में रखते हुए, आपको सेटर्स और गेटर्स से चिपकना होगा - इससे कोई फर्क नहीं पड़ता कि आप उन्हें क्या नाम देते हैं।

+1

मेरा भ्रम यह है कि '.on' और 'isOn' दोनों '- (BOOL) के माध्यम से जा रहे हैं, इसलिए तकनीकी रूप से वे दोनों" सूचना छिपाने "वादे का पालन कर रहे हैं। हालांकि अभी भी सदस्य चर के लिए कोई प्रत्यक्ष पहुंच नहीं है। प्रत्यक्ष पहुंच प्राप्त करने के लिए मुझे '@ public' ivar प्रदान करने के लिए मेरे रास्ते से बाहर जाना होगा और फिर 'myClass -> _' सिंटैक्स –

+0

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

3

अपने प्रयोग से हम इस प्रकार का अनुमान लगा सकते है कि डॉट वाक्य रचना व्याख्या की है:

  • वहाँ इस नाम के साथ एक संपत्ति है? यदि हां, तो क्या इसमें निर्दिष्ट गेटर/सेटर नाम है? यदि हां, तो उस विधि को कॉल करें।
  • अन्यथा, उचित विधि का नाम बनाएं (अगर हम प्राप्त कर रहे हैं, तो सेट करें अगर सेट हो रहा है) और उसे रिसीवर पर फेंक दें।

उदाहरण के लिए, आप .count को एनएसएआरएआरई उदाहरण के विरुद्ध उपयोग करने का प्रयास कर सकते हैं। घृणित पुलिस आपके दरवाजे में लात मारने से पहले, आपके पास यह देखने के लिए समय हो सकता है कि यह काम करता है।

वास्तव में आपके प्रश्न का उत्तर देने के लिए, मेरे दिमाग में डॉट नोटेशन का उपयोग केवल गुणों तक पहुंचने के लिए किया जाना चाहिए, और उस स्थिति में आपको इंटरफ़ेस में घोषित संपत्ति नाम का उपयोग करना चाहिए। तो एक यूआईएसविच के लिए। मुझे नहीं पता कि संपत्ति घोषणा के बजाय संश्लेषण कथन में गेटर नाम क्यों नहीं दिया गया है, ऐसा लगता है कि यह मेरे लिए इंटरफेस के बजाय कार्यान्वयन में है।

+0

मुझे गेटर नाम के बारे में बिंदु पसंद है शायद कार्यान्वयन से संबंधित होना चाहिए। हो सकता है कि मैं इसे गलत कोण से देख रहा हूं, मैं गुणों को केवल एक शॉर्टेंड के रूप में देखता हूं जो मुझे स्पष्ट रूप से इवर और गेटर/सेटर विधियों की घोषणा नहीं करता है। इसलिए गुणों के बिना मैं विधियों की घोषणा करूंगा '- (बूल) है; 'और' - (शून्य) सेटऑन: (बूल);' और वहां 'केवल' तक पहुंच नहीं होगी। फिर उसमें जोड़कर मैं डॉट सिंटैक्स को '- ' और '-सेट ' तक विस्तारित कर रहा हूं, यही कारण है कि मैं उलझन में था कि 'myClass.on'' [myClass isOn] तक विस्तारित प्रतीत होता है; ' –

+0

प्रतिबिंब पर गेटर नाम शायद हेडर में आवश्यक है क्योंकि वह जगह है जहां सार्वजनिक इंटरफ़ेस परिभाषित किया गया है, इसलिए यह समझ में आता है। –

+0

हां, हालांकि मैं बिस्तर पर जाने के बाद भी। संपत्तियों/डॉट नोटेशन को पेश करने से पहले पहले ही उपयोग में है, इसलिए यह एपीआई ग्राहकों को डॉट नोटेशन या विधि कॉल का उपयोग करने की अनुमति देता है, और आईएसएक्स एक बूलियन गेटर के लिए पारंपरिक है क्योंकि यह कोड को और अधिक पठनीय बनाता है। – jrturton

1

संपत्ति घोषणा नियमित विधि घोषणाओं के लिए केवल लघुरूप हैं। उदाहरण के लिए:

- (int)color; 
- (void)setColor:(int)value; 
- (BOOL)isOn; 
- (void)setOn:(BOOL)on; 

तुम बस किसी भी अन्य विधि की तरह इन तरीकों कॉल कर सकते हैं:

[foo color]; 
[foo isOn]; 

इसी तरह, डॉट नोटेशन सादा फोन करने के लिए केवल अनौपचारिक आशुलिपि है

@property int color; 
@property (getter=isOn) BOOL on; 

इन विधि घोषणाओं हो जाता है पुराने तरीकेउदाहरण के लिए:

x = @"Hello".length; 
x = foo.on; 
x = foo.isOn; 

हो जाता है

x = [@"Hello" length]; 
x = [foo isOn]; 
x = [foo isOn]; 

नोट है कि भले ही NSString @"Hello".length काम करता है वास्तव में एक संपत्ति "लंबाई" नाम की घोषणा नहीं करता। डिफ़ॉल्ट रूप से, foo.bar हमेशा [foo bar]तक फैलता है जब तकbar को कस्टम गेटर के साथ एक संपत्ति घोषित कर दी गई है। यदि bar मान्य विधि का नाम होता है तो यह त्रुटि के बिना काम करेगा।

इसी तरह, आपके उदाहरण में foo.isOn काम करता है भले ही आप वास्तव में "isOn" नाम की एक संपत्ति घोषित नहीं करते हैं। इसके बजाय "isOn" एक विधि का नाम है जो आपकी "ऑन" संपत्ति के लिए गेटटर विधि होता है।

तो, जबकि foo.isOn काम कर सकता है, इसे खराब रूप माना जाता है क्योंकि isOn वास्तव में संपत्ति का नाम नहीं है।

x = [foo on]; // Error 

क्योंकि आप एक on प्रणाली की घोषणा कभी नहीं:

क्या आप ऐसा नहीं कर सकते यह है।

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