2010-06-19 4 views
102

उद्देश्य-सी 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 

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

+0

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

उत्तर

94

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

जब आप @synthesize संपत्ति देखते हैं, तो इवर प्रभावी रूप से आपके लिए भी संश्लेषित किया जाएगा। यह "नाजुक-इवर" परिदृश्य के आसपास हो जाता है। आप इसके बारे में Cocoa with Love

69

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

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

@property घोषणा पद्धति आपको अन्य विकल्पों की अनुमति देती है, जैसे कि retain और readonly, जो आवृत्ति परिवर्तनीय घोषणा विधि नहीं है। असल में, ivar पुराना तरीका है, और @property इसे बढ़ाता है और इसे प्रशंसक/आसान बनाता है। आप या तो स्वयं का उपयोग कर सकते हैं। उपसर्ग, या नहीं, इससे कोई फर्क नहीं पड़ता जब तक कि उस वर्ग के लिए नाम अद्वितीय नहीं है। अन्यथा, यदि आपके सुपरक्लस के पास आपके जैसा संपत्ति का वही नाम है, तो आपको यह निर्दिष्ट करने के लिए कि आप किस नाम के बारे में बात कर रहे हैं, स्वयं को self.name या super.name जैसा कहना है।

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

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

+3

उत्कृष्ट स्पष्टीकरण .. –

+0

वास्तव में उत्कृष्ट – Fab1n

+1

इस उत्तर ने मेरे लिए भ्रम के सप्ताहों को मंजूरी दे दी! –

3

प्रलेखन से:

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

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

8

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

1

The Objective-C Programming Language: Property Implementation Directives

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

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

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

3

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

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

@property (nonatomic, strong) NSString *name; 

यह रूप में

@synthesize name = _name; 

कोड synthesizing उत्पन्न होगा और आप

NSString* _name 

घोषित करने के लिए नाम_ यह इसी तरह की है का उपयोग कर उदाहरण चर का उपयोग कर सकते हैं, लेकिन आप केवल पढ़ने के लिए यह संपत्ति घोषणा करते हैं जैसे

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

यह कोड

@synthesize name; 

या

@synthesize name = name; 

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

@synthesize name = _name; 
संबंधित मुद्दे