2008-11-08 14 views
22

में ivar संश्लेषण के लिए अंतर्निहित तंत्र क्या है आधुनिक (64 बिट ओएस एक्स और आईफोन ओएस) उद्देश्य सी रनटाइम की विशेषताओं में से एक है गुणों को गतिशील रूप से इन्हें बिना घोषित किए इवर्स को संश्लेषित करने की क्षमता वर्ग:आधुनिक उद्देश्य सी रनटाइम

@interface MyClass : NSObject { 
// NSString *name; unnecessary on modern runtimes 
} 

@property (retain) NSStrng *name; 

@end 

@implementation MyClass 

@synthesize name; 

@end 

काफी मेरे कोड का एक सा में मैं क्रम में कस्टम गेटर कार्यान्वयन का उपयोग गुण प्रारंभ करने में:

- (NSString *) name { 
    if (!name) { 
    name = @"Louis"; 
    } 

    return name; 
} 

ऊपर के बाद से यह एक एक का उपयोग करने की जरूरत है संश्लेषित ivars के साथ असंगत है ivar कि घोषणा नहीं है हेडर में एड। विभिन्न कारणों से मैं आधुनिक रनटाइम्स पर बनाए गए संश्लेषित इवर्स का उपयोग करने के लिए अपने कई व्यक्तिगत ढांचे को अपडेट करना चाहता हूं, उपरोक्त कोड को उस लक्ष्य को प्राप्त करने के लिए संश्लेषित इवर के साथ काम करने के लिए संशोधित करने की आवश्यकता है।

उद्देश्य सी 2.0 दस्तावेज बताता है कि आधुनिक रनटाइम पर संश्लेषित एक्सेसर्स पहले उपयोग पर ivar को संश्लेषित करेंगे। यह निर्दिष्ट नहीं करता है कि ऐसा करने के लिए निम्न स्तर की तंत्र का उपयोग किया जाता है। क्या यह class_getInstanceVariable() द्वारा किया जाता है, class_addIvar() loosened पर प्रतिबंध हैं, क्या यह एक अनियंत्रित फ़ंक्शन int है जिसका उद्देश्य सी 2.0 रनटाइम है? जबकि मैं अपने गुणों का समर्थन करने वाले डेटा के लिए अपने स्वयं के साइड स्टोरेज को कार्यान्वित कर सकता हूं, लेकिन मैं उस तंत्र का उपयोग करता हूं जो एक्सेसर्स का उपयोग कर रहे हैं।

+1

मैं सच में प्रभावित करता है, तो आप जीसीसी के सिंथेसाइज़र कोड को पढ़ने के बाद इस – Shawn

उत्तर

21

मैं गया और अभी दस्तावेज़ों को फिर से देखा, और मुझे लगता है कि आप इसे गलत तरीके से पढ़ रहे हैं। संश्लेषित ivars संकलन समय पर बनाए जाते हैं, रन समय पर नहीं।

Objective-C 2.0 documentation के अनुसार:

उस क्रम पर निर्भर व्यवहार में मतभेद हैं (यह भी देखें "रनटाइम मतभेद"):

विरासत runtimes के लिए, उदाहरण चर पहले से ही घोषित किया जाना चाहिए @interface ब्लॉक में। यदि समान नाम और संगत प्रकार का एक उदाहरण चर मौजूद है, तो इसका उपयोग किया जाता है-अन्यथा, आपको एक कंपाइलर त्रुटि मिलती है।

आधुनिक रनटाइम के लिए, आवृत्ति चर आवश्यकतानुसार संश्लेषित होते हैं। यदि एक ही नाम का एक इंस्टेंस वैरिएबल पहले से मौजूद है, तो इसका उपयोग किया जाता है।

तो तुम सब करने की जरूरत है उदाहरण चर आप की जरूरत की घोषणा है, और एक ही कोड दोनों runtimes पर काम करेंगे ...

+2

का उत्तर मिल गया होगा यह वास्तव में क्या है चल रहा। –

+1

एक्सकोड 3.2 युग कंपाइलर्स (क्लैंग/एलएलवीएम और जीसीसी 4.2) में सुधारों में से एक यह है कि आप उन हिस्सों तक पहुंच सकते हैं जो संश्लेषित चरों को वापस करने के लिए बनाए जाते हैं, भले ही उन्हें कक्षा में घोषित न किया गया हो, जो इससे कुछ हद तक म्यूट हो जाता है । –

-6

आप NSKeyValueCoding Protocol साथ रन-टाइम में गुण जोड़ें।

[myObject setValue:@"whatever" forKey:@"foo"]; 
+2

यह गलत है। आप कुंजी-मूल्य कोडिंग के साथ * सेट * सेट कर सकते हैं, लेकिन आप इस तरह से गुण जोड़ नहीं सकते हैं। – jlehr

+0

यदि कक्षा उस प्रोटोकॉल को लागू करती है तो आप बिल्कुल NSKeyValueCoding के साथ नए मान जोड़ सकते हैं। लेकिन आप सही हैं, कि इस प्रश्न का गलत जवाब है क्योंकि आईवीआर संकलन समय पर बनाए जाते हैं, न कि NSKeyValueCoding के साथ। – jazzdev

+1

उत्तर दोबारा पढ़ें। आप कुंजी-मूल्य कोडिंग के माध्यम से * गुण * जोड़ नहीं सकते हैं। – jlehr

0

क्या आप के लिए, नाम @synthesized है की तरह देख रहे हैं:

@synthesize name = _name; 

... 

- (NSString *) name { 
    if (!name) { 
     _name = @"Louis"; 
    } 

    return _name; 
} 
संबंधित मुद्दे