क्या उद्देश्य-सी में "उदाहरण चर" और "संपत्ति" के बीच अंतर है?
मैं इस बारे में निश्चित नहीं हूं। मुझे लगता है कि "प्रॉपर्टी" एक इंस्टेंस वैरिएबल है जिसमें एक्सेसर तरीके होते हैं, लेकिन मैं गलत सोच सकता हूं।
जवाबों:
एक संपत्ति एक अधिक अमूर्त अवधारणा है। एक इंस्टा वेरिएबल वस्तुतः एक स्टोरेज स्लॉट है, जैसे किसी स्ट्रक्चर में स्लॉट। आम तौर पर अन्य वस्तुओं को कभी भी सीधे उन तक नहीं पहुंचना चाहिए। दूसरी ओर एक संपत्ति, आपकी वस्तु की एक विशेषता है जिसे एक्सेस किया जा सकता है (यह अस्पष्ट लगता है और इसे माना जाता है)। आमतौर पर एक संपत्ति वापस आ जाएगी या एक उदाहरण चर सेट कर सकती है, लेकिन यह कई या किसी से डेटा का उपयोग नहीं कर सकता है। उदाहरण के लिए:
@interface Person : NSObject {
NSString *name;
}
@property(copy) NSString *name;
@property(copy) NSString *firstName;
@property(copy) NSString *lastName;
@end
@implementation Person
@synthesize name;
- (NSString *)firstName {
[[name componentsSeparatedByString:@" "] objectAtIndex:0];
}
- (NSString *)lastName {
[[name componentsSeparatedByString:@" "] lastObject];
}
- (NSString *)setFirstName:(NSString *)newName {
NSArray *nameArray = [name componentsSeparatedByString:@" "];
NSArray *newNameArray [[NSArray arrayWithObjects:newName, nil] arrayByAddingObjectsFromArray:[nameArray subarrayWithRange:NSMakeRange(1, [nameArray size]-1)]];
self.name = [newNameArray componentsJoinedByString:@" "];
}
- (NSString *)setLastName:(NSString *)newName {
NSArray *nameArray = [name componentsSeparatedByString:@" "];
NSArray *newNameArray [[nameArray subarrayWithRange:NSMakeRange(0, [nameArray size]-2)] arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:newName, nil]];
self.name = [newNameArray componentsJoinedByString:@" "];
}
@end
(नोट: उपरोक्त कोड इस तरह से छोटी है कि यह पहले से मौजूद नाम को मानता है और इसमें कम से कम दो घटक हैं (उदाहरण के लिए "गेट्स" के बजाय "बिल गेट्स")। मुझे लगा कि उन मान्यताओं को ठीक करने से कोड का वास्तविक बिंदु बन जाएगा। कम स्पष्ट है, इसलिए मैं इसे यहाँ इंगित कर रहा हूँ ताकि कोई भी उन गलतियों को दोहराए नहीं। "
एक संपत्ति अतिरिक्त उपयोगी सुविधाओं और वाक्यविन्यास के साथ कुछ मूल्य के लिए एक गेट्टर / सेटर को लागू करने का एक अनुकूल तरीका है। एक संपत्ति को एक उदाहरण चर द्वारा समर्थित किया जा सकता है, लेकिन आप कुछ और अधिक गतिशील करने के लिए गेटटर / सेटर को भी परिभाषित कर सकते हैं, जैसे आप एक स्ट्रिंग पर एक लोअरकेस संपत्ति को परिभाषित कर सकते हैं जो गतिशील रूप से कुछ सदस्य के मूल्य को वापस करने के बजाय परिणाम बनाता है। चर।
यहाँ एक उदाहरण है:
// === In your .h ===
@interface MyObject {
NSString *propertyName;
}
// ...
@property (nonatomic, retain) NSString *propertyName;
// === In your .m @implementation ===
@synthesize propertyName /* = otherVarName */;
@propertyलाइन एक संपत्ति बुलाया परिभाषित करता है propertyNameप्रकार के NSString *। यह निम्नलिखित सिंटैक्स का उपयोग करके प्राप्त / सेट किया जा सकता है:
myObject.propertyName = @"Hello World!";
NSLog("Value: %@", myObject.propertyName);
जब आप असाइन करते हैं या myObject.propertyNameआपसे पढ़ते हैं तो आप वास्तव में ऑब्जेक्ट पर सेटर / गेट्टर विधियों को बुला रहे हैं।
@synthesizeलाइन आपके लिए इन गटर / सेटर को उत्पन्न करने के लिए संकलक को बताती है, मान को संग्रहीत करने के लिए संपत्ति के समान नाम के साथ सदस्य चर का उपयोग करके (या otherVarNameयदि आप टिप्पणियों में वाक्य रचना का उपयोग करते हैं)।
इसके साथ ही @synthesizeआप अपने स्वयं के परिभाषित करने के बाद भी किसी एक ग्राईटर / सेटर को ओवरराइड कर सकते हैं। इन विधियों के लिए नामकरण सम्मेलन setPropertyName:सेटर के लिए और propertyName(या getPropertyName, मानक नहीं) के लिए है। दूसरे अभी भी आपके लिए उत्पन्न होंगे।
अपनी @propertyलाइन में आप संपत्ति के लिए कई विशेषताओं को परिभाषित कर सकते हैं, जो थ्रेड-सुरक्षा और मेमोरी प्रबंधन जैसी चीजों को स्वचालित कर सकती हैं। डिफ़ॉल्ट रूप से एक संपत्ति परमाणु अर्थ है कंपाइलर @synthesizसमवर्ती मुद्दों को रोकने के लिए उचित लॉक के साथ एड गेट / सेट कॉल लपेटेगा। आप इसे nonatomicअक्षम करने के लिए विशेषता निर्दिष्ट कर सकते हैं (उदाहरण के लिए iPhone पर जिसे आप अधिकांश गुणों को डिफ़ॉल्ट करना चाहते हैं nonatomic)।
3 विशेषता मान हैं जो किसी भी @synthesizedबसने वालों के लिए स्मृति प्रबंधन को नियंत्रित करते हैं । पहला वह है retainजो स्वचालित रूप releaseसे संपत्ति के पुराने मूल्यों को भेजेगा , और retainनए मूल्यों को। यह बहुत उपयोगी है।
दूसरा वह है copyजो उन्हें बनाए रखने के बजाय पारित किए गए किसी भी मूल्य की प्रतिलिपि बना देगा। copyNSString के लिए उपयोग करना अच्छा है क्योंकि एक कॉल करने वाला व्यक्ति NSMutableString में पास हो सकता है और इसे आपके नीचे से बदल सकता है। copyउस इनपुट की एक नई प्रति बनाएगा, जिस पर केवल आपकी पहुंच हो।
तीसरा वह है assignजो पुराने या नए ऑब्जेक्ट पर बनाए रखने / जारी किए बिना सीधे पॉइंटर असाइन करता है।
अंत में आप readonlyसंपत्ति के लिए सेटर को निष्क्रिय करने के लिए विशेषता का भी उपयोग कर सकते हैं।
मैं इंटरफ़ेस भाग के लिए गुणों का उपयोग करता हूं - जहां ऑब्जेक्ट अन्य ऑब्जेक्ट्स और उदाहरण चर के साथ इंटरफेस करता है, जो आपको अपनी कक्षा के अंदर चाहिए - कोई नहीं लेकिन आपको उन लोगों को देखने और हेरफेर करने वाला है।
डिफ़ॉल्ट रूप से, एक रीडायरेक्ट प्रॉपर्टी एक उदाहरण चर द्वारा समर्थित होगी, जिसे फिर से संकलक द्वारा स्वचालित रूप से संश्लेषित किया जाएगा।
एक उदाहरण चर एक चर है जो मौजूद है और वस्तु के जीवन के लिए अपना मूल्य रखता है। उदाहरण के चर के लिए उपयोग की जाने वाली मेमोरी तब आवंटित की जाती है जब ऑब्जेक्ट पहली बार (आवंटन के माध्यम से) बनाया जाता है, और ऑब्जेक्ट डीलहोल्ड होने पर मुक्त हो जाता है।
जब तक आप अन्यथा निर्दिष्ट नहीं करते हैं, संश्लेषित उदाहरण चर का एक ही नाम संपत्ति है, लेकिन एक अंडरस्कोर उपसर्ग के साथ। पहले नाम वाली संपत्ति के लिए, उदाहरण के लिए, संश्लेषित उदाहरण चर को _firstName कहा जाएगा।
पहले के लोग निजी उपयोग के लिए सार्वजनिक रूप से और ivars के गुणों का उपयोग करते हैं, लेकिन कई साल पहले से, आप @implementationनिजी रूप से उपयोग करने के लिए गुणों को भी परिभाषित कर सकते हैं । लेकिन मैं अभी भी जब संभव हो तो ivars का उपयोग करूँगा, क्योंकि टाइप करने के लिए कम अक्षर हैं, और यह इस लेख के अनुसार तेजी से चलता है । यह समझ में आता है क्योंकि संपत्तियों को "भारी" होने का मतलब है: वे या तो उत्पन्न गेटर्स / सेटर्स या मैन्युअल रूप से लिखे गए लोगों से एक्सेस किए जाने वाले हैं।
हालाँकि, Apple के हाल के कोड में, आइवर का उपयोग नहीं किया जाता है। मुझे लगता है कि क्योंकि यह अधिक की तरह है objcके बजाय C/C++, के साथ साथ इसके साथ गुण उपयोग करना आसान हो assign, nullableआदि
@implementationस्विफ्ट के साथ समानता दिखाने के लिए गुणों का उपयोग सेब करता है । फिर भी मैं अपने स्वयं के वर्ग के एक साधारण क्षेत्र को देखने के लिए एक आभासी फ़ंक्शन कॉल को बर्बाद न करने के लिए बैकिंग चर को प्राथमिकता देता हूं (और यह तब होता है जब संपत्ति तक पहुंच होती है)।