क्या घोषित संपत्तियों को एक समान उदाहरण चर की आवश्यकता होती है?


101

क्या उद्देश्य-सी 2.0 में संपत्तियों को घोषित किए जाने के लिए संबंधित आवृत्ति चर की आवश्यकता होती है? उदाहरण के लिए, मैं कुछ ऐसा करने के लिए उपयोग किया जाता हूं:

MyObject.h

@interface MyObject : NSObject {
NSString *name;
}
@property (nonatomic, retain) NSString *name;
@end

MyObject.m

@implementation
@synthesize name;
@end

हालाँकि, अगर मैंने इसके बजाय यह किया है:

MyObject.h

@interface MyObject : NSObject {
}
@property (nonatomic, retain) NSString *name;
@end

क्या यह अभी भी वैध है? और क्या यह किसी भी तरह से मेरे पिछले उदाहरण से अलग है?


दूसरा 'MyObject.h' बोल्ड में क्यों नहीं 'MyObject.m' है?
रिओमायर

जवाबों:


93

यदि आप मॉडर्न ऑब्जेक्टिव-सी रनटाइम (जो कि iOS 3.x या उससे अधिक है, या 64-बिट स्नो लेपर्ड या अधिक है) का उपयोग कर रहे हैं, तो आपको इस तरह के मामलों में अपने गुणों के लिए ivars को परिभाषित करने की आवश्यकता नहीं है।

जब आप @synthesizeसंपत्ति बनाते हैं, तो आइवर आपके लिए भी संश्लेषित हो जाएगा। यह "नाजुक-आइवर" परिदृश्य के आसपास मिलता है। आप कोको ऑन लव के बारे में अधिक पढ़ सकते हैं


71

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

आप हमेशा ऑटो-कोडेड गेट्टर / सेटर को ओवरराइड कर सकते हैं अपने स्वयं के निर्दिष्ट करके। यह आमतौर पर उस managedObjectContextसंपत्ति के साथ किया जाता है जो आलसी लोडेड है। इस प्रकार, आप अपनी managedObjectContextसंपत्ति घोषित करते हैं, लेकिन फिर एक भी लिखते हैं-(NSManagedObjectContext *)managedObjectContext विधि । उस विधि को याद करें, जिसका उदाहरण चर / संपत्ति के समान नाम है, "गेट्टर" विधि है।

@propertyघोषणा विधि भी आप इस तरह के रूप में अन्य विकल्प, की अनुमति देता है retainऔर readonlyहै, जो उदाहरण चर घोषणा विधि नहीं है। मूल रूप से, ivarपुराना तरीका है, और @propertyइसे विस्तारित करता है और इसे कट्टर / आसान बनाता है। आप स्वयं का उपयोग करके या तो संदर्भित कर सकते हैं। उपसर्ग, या नहीं, यह तब तक मायने नहीं रखता जब तक कि नाम उस वर्ग के लिए अद्वितीय न हो। अन्यथा, यदि आपके सुपरक्लास में आपके जैसी ही संपत्ति का नाम है, तो आपको यह बताने के लिए स्व.नाम या सुपर.नाम की तरह या तो यह कहना होगा कि आप किस नाम के बारे में बात कर रहे हैं।

इस प्रकार, आप कम और कम लोगों ivarको ब्रेसिज़ के बीच एस घोषित करते हैं , और इसके बजाय सिर्फ निर्दिष्ट करने की ओर शिफ्ट होते हैं @property, और फिर कर रहे हैं @synthesize। आप इसके @synthesizeबिना अपने कार्यान्वयन में नहीं कर सकते @property। सिंथेसाइज़र केवल यह जानता है कि यह किस प्रकार की विशेषता है @property। सिंथेसाइज़ स्टेटमेंट आपको संपत्तियों का नाम बदलने की भी अनुमति देता है, ताकि आप अपने कोड के अंदर एक नाम (आशुलिपि) द्वारा एक संपत्ति का उल्लेख कर सकें, लेकिन .h फ़ाइल के बाहर पूर्ण नाम का उपयोग करें। हालाँकि, XCode के पास वास्तव में अच्छा स्वत: पूर्ण होने के साथ, यह एक लाभ से कम है, लेकिन अभी भी है।

आशा है कि यह सब भ्रम और गलत सूचनाओं को दूर करने में मदद करता है जो वहां से बाहर चल रही है।


अब किसी दिन @synthesize लिखना अनिवार्य नहीं है। उस स्थिति में यह उत्तर कैसे मान्य है!
10

आपको <code> @property ... @ सिंथेसाइज़ </ कोड> घोषित करने की ज़रूरत नहीं है। सिंथेसाइज़ का उपयोग करने से आपको कार्यान्वयन में एक गेटटर / सेटर लिखने के लिए राहत मिलती है। यदि आप संश्लेषित नहीं करते हैं, तो आपको अपना खुद का
गेट्टर

2
@PapaSmurf यह गलत है। आप उपयोग कर सकते हैं @property, और उपयोग नहीं कर सकते हैं और @synthesizeउन्हें स्वयं लागू नहीं कर सकते हैं। कंपाइलर synthesizeआपके लिए ऑटो करेगा , जो अब और लिखे बिना।
jbrennan

8

यह दोनों तरीकों से काम करता है, लेकिन यदि आप उन्हें घुंघराले ब्रेसिज़ में घोषित नहीं करते हैं, तो आप उनके मानों को xcode में डीबगर में नहीं देखेंगे।


3

प्रलेखन से:

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

विरासत रनटाइम में काम करने के लिए @synthesize के लिए, आपको या तो एक ही नाम और संगत प्रकार की संपत्ति के साथ एक उदाहरण चर प्रदान करना होगा या @synthesize स्टेटमेंट में किसी अन्य मौजूदा आवृत्ति चर को निर्दिष्ट करना होगा। आधुनिक रनटाइम के साथ, यदि आप एक उदाहरण चर प्रदान नहीं करते हैं, तो संकलक आपके लिए एक जोड़ता है।


3

यदि आप XCode 4.4 या बाद का उपयोग कर रहे हैं तो यह आपके लिए उदाहरण चर संश्लेषण कोड उत्पन्न करेगा।

आपको बस नीचे दिए गए गुणों को घोषित करना होगा; यह आपके लिए सिंथेसाइज़िंग कोड और इंस्टेंस वेरिएबल कोड घोषित करने वाला जेनरेट करेगा।

@property (nonatomic, strong) NSString *name;

के रूप में यह संश्लेषित कोड उत्पन्न करेगा

@synthesize name = _name;

और आप _name का उपयोग करके उदाहरण चर का उपयोग कर सकते हैं यह घोषित करने के समान है

NSString* _name

लेकिन अगर आप पठन-योग्य संपत्ति की घोषणा करते हैं तो यह पसंद है

@property (nonatomic, strong, readonly) NSString *name;

यह कोड उत्पन्न करेगा

@synthesize name;

या

@synthesize name = name; 

तो आपको किसी भी तरह से उपसर्ग चर नाम का उपयोग करना चाहिए "_" जिस तरह से आप अपना खुद का सिंथेसाइजिंग कोड लिख सकते हैं तो कंपाइलर आपके लिए कोड उत्पन्न करेगा। तुम लिख सकते हो

@synthesize name = _name;

1

उद्देश्य-सी प्रोग्रामिंग भाषा: संपत्ति कार्यान्वयन निर्देश

गौण संश्लेषण के व्यवहार में अंतर होते हैं जो रनटाइम पर निर्भर करते हैं ("रनटाइम अंतर" भी देखें))

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

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.