दिलचस्प पोस्ट
Textarea में HTML प्रदान करना एंड्रॉइड फोन एक दूसरे के समाप्त होने के तुरंत बाद AsyncTask कैसे परीक्षण करें कि एक अजगर मॉड्यूल आयात किया गया है? जेवा में एक्सेल शीट पढ़ने के लिए बेहतर एपीआई क्या है – जेएक्सएल या अपाचे पीओआई क्यों jQuery या एक DOM विधि जैसे getElementById तत्व नहीं मिल रहा है? एंड्रॉइड ऐप पर एसएमएस प्राप्त करना .NET से X.509 प्रमाण पत्र की निजी कुंजी फाइल पर पढ़ने की अनुमति कैसे सेट करें I अर्ध पारदर्शी ओवरले छवि को कुछ नियंत्रणों वाले सभी खिड़कियों पर खींचें सिंगल कोट्स बनाम डबल कोट्स सी या सी ++ में नाम से res / raw फ़ाइल को कैसे पढ़ा जाए dyld: प्रतीक नहीं मिला: _NSURLAIThenticationMethodClientCertificateIOS एप को चलाने का प्रयास करते समय एकल-विधानसभा बहुभाषी विंडोज़ फार्म तैनाती (आईएलएमर्गे और सैटेलाइट असेंबली / स्थानीयकरण) – संभव है? क्रैश लॉग का प्रतीक करने के लिए Xcode 4 विफलता आप इस टूटे हुए यादृच्छिक शफल से क्या वितरण प्राप्त करते हैं? वर्ड डॉक को प्रोग्राम में एचटीएमएल में परिवर्तित करें

संपत्ति बनाम उदाहरण चर

मैं यह समझने की कोशिश कर रहा हूं कि रणनीतियों का उपयोग कुछ लोग उदाहरण वाले वर्क्स बनाम संपत्तियों में अंतर करने के लिए करते हैं। एक आम पैटर्न निम्नलिखित है:

@interface MyClass : NSObject { NSString *_myVar; } @property (nonatomic, retain) NSString *myVar; @end @implementation MyClass @synthesize myVar = _myVar; 

अब, मैंने सोचा था कि इस रणनीतियों के पीछे का पूरा परिपालन इतना है कि एक आसानी से एक ivar और संपत्ति के बीच अंतर भेद कर सकते हैं। इसलिए, अगर मैं एक संश्लेषित संपत्ति से विरासत में मिली स्मृति प्रबंधन का उपयोग करना चाहता हूं, तो मैं कुछ ऐसा प्रयोग करूँगा जैसे:

 myVar = @"Foo"; 

दूसरा तरीका इसे स्वयं के माध्यम से संदर्भित करेगा। [Ivar / property here]

@ संवेदक myVar = _myVar रणनीति का प्रयोग करने में समस्या, मुझे लगा है कि लेखन कोड जैसे:

 myVar = some_other_object; // doesn't work. 

कंपाइलर शिकायत करता है कि myVar अघोषित है वह मामला क्या है?

धन्यवाद।

वेब के समाधान से एकत्रित समाधान "संपत्ति बनाम उदाहरण चर"

गुण केवल ivars लिए सेटर्स और ivars और सीधे एक्सेस के बजाय (लगभग) हमेशा उपयोग किए जाने चाहिए।

 @interface APerson : NSObject { // NSString *_name; // necessary for legacy runtime } @property(readwrite) NSString *name; @end @implementation APerson @synthesize name; // use name = _name for legacy runtime @end 

@synthesize इस मामले में उन दो तरीकों (नहीं 100% सटीक) बनाता है:

 - (NSString *)name { return [[_name copy] autorelease]; } - (void)setName:(NSString *)value { [value retain]; [_name release]; _name = value; } 

ivars और गेटर्स / सेटर्स के बीच अंतर करने के लिए अब यह आसान है। एक्सेसर्स को self. मिल गया है उपसर्ग। आपको वैसे भी वैसे भी सीधे एक्सेस नहीं करना चाहिए।


आपका नमूना कोड काम नहीं करता जैसा कि यह होना चाहिए:

 _myVar = some_other_object; // _myVar is the ivar, not myVar. self.myVar = some_other_object; // works too, uses the accessors 

prop नामित एक संश्लेषित संपत्ति वास्तव में दो विधियों prop (संपत्ति के वर्तमान मूल्य को वापस) और setProp: (सहारा के लिए एक नया मान सेट करना) द्वारा setProp:

self.propself.prop सिंटैक्स इन self.prop किसी एक को कॉल करने के लिए वाक्यविन्यास चीनी है। आपके उदाहरण में, संपत्ति myVar सेट करने के लिए आप निम्न में से कोई एक कर सकते हैं:

 self.myVar = @"foo"; // handles retain/release as specified by your property declaration [self setMyVar: @"foo"]; // handle retain/release _myVar = @"Foo"; // does not release old object and does not retain the new object 

गुणों का उपयोग करने के लिए, self.propname प्रयोग self.propnameself.propname उदाहरण चर का उपयोग करने के लिए बस उदाहरण चर का नाम का उपयोग करें।

@ संवेदक myVar = _myVar रणनीति का प्रयोग करने में समस्या, मुझे लगा है कि लेखन कोड जैसे:

 myVar = some_other_object; // doesn't work. 

कंपाइलर शिकायत करता है कि myVar अघोषित है वह मामला क्या है?

क्योंकि चर myVar अघोषित है

यह कथन वाक्यविन्यास का उपयोग किसी चर के उपयोग के लिए करता है, यह एक उदाहरण चर या कुछ अन्य प्रकार जैसा कि राविनविंड ने आपको बताया, एक संपत्ति का उपयोग करने के लिए, आपको प्रॉपर्टी-एक्सेस सिंटैक्स ( self.myVar = someOtherObject ) या self.myVar = someOtherObject विधि के लिए एक स्पष्ट संदेश ( [self setMyVar:someOtherObject] ) का उपयोग करना होगा।

अन्यथा, आप एक वेरिएबल तक पहुंचने का प्रयास कर रहे हैं, और जब से आपके पास अपना वैरिएबल नाम नहीं है, तो आप एक वेरिएबल तक पहुंचने का प्रयास कर रहे हैं जो मौजूद नहीं है।

सामान्य तौर पर, मैं अपनी संपत्तियों को मेरे उदाहरण चर के समान नाम देता हूं; यह डिफ़ॉल्ट धारणा है कि @property सिंटैक्स बनाता है यदि आपको लगता है कि आप चूक से लड़ रहे हैं, तो आप इसे गलत कर रहे हैं (या आपके फ्रेमवर्क सूक्स, जो कि मेरी राय में कोको / कोको-टच के लिए मामला नहीं है)।

आपके द्वारा प्राप्त की जा रही संकलक त्रुटि यह है कि संपत्ति का उपयोग हमेशा अपने वर्ग के कार्यान्वयन के भीतर भी एक ऑब्जेक्ट संदर्भ होना चाहिए:

 self.stuff = @"foo"; // property setter [stuff release]; // instance variable stuff = @"bar"; // instance variable return self.stuff; // property getter 

मुझे पता है कि कई कोको प्रोग्रामर असहमत हैं, लेकिन मुझे लगता है कि यह आपके क्लास कार्यान्वयन के अंदर गुणों का उपयोग करने के लिए खराब अभ्यास है। मैं इस तरह कुछ देखना चाहता हूं:

 -(void) someActionWithStuff: (NSString*) theStuff { // do something [stuff release]; stuff = [theStuff copy]; // do something else } 

उसके बाद यह:

 -(void) someActionWithStuff: (NSString*) theStuff { // do something self.stuff = theStuff; // do something else } 

मैं मेमोरी प्रबंधन को यथासंभव स्पष्ट रूप से करना पसंद करता हूं। लेकिन भले ही आप असहमत हों, self.stuff का इस्तेमाल करते self.stuff फॉर्म फॉर्म किसी भी अनुभवी उद्देश्य- C प्रोग्रामर में सुराग करेंगे कि आप किसी आवृत्ति चर को एक्सेस करने के बजाय संपत्ति बुला रहे हैं यह एक सूक्ष्म बिंदु है, शुरुआती लोगों के लिए आसान है, लेकिन कुछ समय के लिए उद्देश्य-सी 2.0 के साथ काम करने के बाद, यह बहुत स्पष्ट है।

डॉन,

"नियम" के अनुसार, आपको प्रत्येक प्रतिलिपि, आबंटन, और बनाए रखने के लिए रिलीज पर कॉल करना चाहिए। तो आप सामान पर रिलीज क्यों कॉल कर रहे हैं? क्या यह संभालने यह Alloc, Copy, या Retain का उपयोग कर बनाया गया था?

यह एक और सवाल उठाता है: क्या यह किसी भी ऑब्जेक्ट के संदर्भ में रिलीज को कॉल करने में हानिकारक है, अगर वह पहले ही रिलीज़ हो चुका है?

चूंकि ऐप्पल खुद के लिए _ उपसर्ग आरक्षित रखता है, और जब से मैं इसे अधिक स्पष्ट करना चाहता हूँ जब मैं सेटर का उपयोग कर रहा हूं और जब मैं आईवर का उपयोग कर रहा हूं, तो मैं अपने आईवरों पर i_ के एक उपसर्ग का उपयोग करने के लिए अपनाया है, उदाहरण के लिए :

 @interface MyClass : NSObject { NSString *i_myVar; } @property (nonatomic, retain) NSString *myVar; @synthesize myVar = i_myVar; i_myVar = [input retain]; self.myVar = anotherInput; [i_myVar release] 

चूंकि यह जानना काफी महत्वपूर्ण है कि आप कब सेटर का उपयोग कर रहे हैं और जब आप आईवर का उपयोग कर रहे हैं, तो मुझे पता लगता है कि अलग-अलग नाम सुरक्षित है।

आपके प्रश्न में, यह होना चाहिए:

 self.myVar = @"Foo"; // with setter, equivalent to [self setMyVar:@"Foo"] 

तथा

 _myVar = some_other_object; // direct ivar access - no memory management! 

याद रखें कि आपको init / dealloc में सेटर्स / गेटर्स का उपयोग नहीं करना चाहिए, इसलिए आपको अपने डायरेक्ट ivar एक्सेस (और सावधान मेमोरी मैनेजमेंट) को उन विधियों के लिए करना चाहिए।

बस का उपयोग करने के साथ क्या गलत है

 @interface MyClass : NSObject @property NSString *prop; @end 

nonatomic और बनाए रखने की आवश्यकता नहीं है, बनाए रखने डिफ़ॉल्ट है, और परमाणु / nonatomic महत्वपूर्ण नहीं है जब तक XCode आपको एक चेतावनी के साथ बताता है

यह iVar घोषित करने के लिए आवश्यक नहीं है, आपके लिए _prop नाम का एक बनाया जाएगा, अगर आप वास्तव में एक का उपयोग करना चाहते हैं (मुझे पता नहीं क्यों ईमानदार होना चाहिए)

@ संश्लेषण की आवश्यकता नहीं है

जब (और आपको एआरसी का प्रयोग करना चाहिए) आपको परेशान करने की आवश्यकता नहीं है और इसे छोड़ने की आवश्यकता नहीं है।

इसे सरल रखें !

इसके अलावा, अगर आपके पास इस तरह की कोई विधि है

 - (void)aMethod:(NSString*)string { self.prop = string; // shows very clearly that we are setting the property of our object _aName = string; // what is _aName ? the _ is a convention, not a real visual help } 

मैं हमेशा गुणों का उपयोग करता हूं, अधिक लचीला, पढ़ने के लिए आसान।