2011-11-01 9 views
6

कोड में जो मैं विरासत में हूं, मैंने निम्न को देखा है:आईबीओलेट काम के लिए केवल पढ़ने योग्य संपत्ति है और क्या यह पसंदीदा होगा?

@property (readonly) IBOutlet UIImageView * bgImage; 

जब मैं एक मेमोरी मॉडल को बनाए रखने की अपेक्षा करता हूं जैसे:

@property (readonly, retain) IBOutlet UIImageView * bgImage; 

मुझे उलझन में है कि पहली संपत्ति परिभाषा क्यों काम करती है समस्याओं के बिना।

इसके अलावा, डेलोक में एक release है जैसा कि आप उम्मीद कर सकते हैं:

-(void)dealloc 
{ 
    [_bgImage release]; 
    [super dealloc]; 
} 

अगर कोई इसके लिए स्पष्टीकरण के साथ आ सकता है तो मैं सराहना करता हूं। मैंने मूल डेवलपर से बात की है और वह अधिक संक्षिप्त कोड लिखने की कोशिश कर रहा था, यही कारण है कि उसने स्मृति मॉडल में retain छोड़ा (अनावश्यक लग रहा था)।

मुझे आश्चर्य है कि आईबीओलेटलेट को मूल रूप से ivar IBOutlet कथन की तरह माना जाता है क्योंकि यह केवल पढ़ने के लिए है (उपयोग करने के लिए कोई सेटटर नहीं है, इस प्रकार डिफ़ॉल्ट असाइन मेमोरी मॉडल कोई फर्क नहीं पड़ता)।

यदि आईबीओलेटलेट को कभी भी बदलने की उम्मीद नहीं की जाती है, तो रीडोनली प्रॉपर्टी का उपयोग करना बिना मेमोरी मॉडल के गुणों को परिभाषित करने का एक बेहतर तरीका है?

उत्तर

7

आईओएस पर निब लोडर एनआईबी में ऑब्जेक्ट बनाता है और फिर उन्हें ऑटोरेलेज़ करता है। जब यह आउटलेट से कनेक्शन स्थापित करता है, तो यह setValue:forKey: का उपयोग करता है, जो उस कुंजी के लिए सेटटर विधि को कॉल करेगा। यदि कोई सेटर परिभाषित नहीं किया गया है, जैसे कि IBOutletreadonly संपत्ति है, तो ऑब्जेक्ट को किसी भी तरह असाइन किए जाने से पहले बनाए रखा जाता है।

वास्तविक तथ्य

तो (यह संसाधन प्रोग्रामिंग गाइड में Managing Nib Objects in iOS की एक संक्षिप्त व्याख्या है।), आउटलेट retain या assign, दूसरे छोर पर वस्तु है आउटलेट के साथ वस्तु के स्वामित्व के रूप में घोषित किया गया है या । या तो इसे सेटर विधि द्वारा बनाए रखा जाता है, या एक सेटर नहीं मिलने पर इसे setValue:forKey: द्वारा बनाए रखा जाता है। चूंकि दूसरे मामले में कोई अन्य संभावित मालिक नहीं है, इसलिए आप वस्तु को आउटलेट के मालिक के रूप में मान सकते हैं। इसलिए निब में ऑब्जेक्ट dealloc में जारी किया जाना चाहिए।

मैं आपसे सहमत हूं कि retain शामिल करने के लिए संपत्ति विशेषताओं को बदलकर इस स्मृति की स्थिति को स्पष्ट किया जाना चाहिए। * readonly कोई फर्क नहीं पड़ता है (हालांकि, नीचे देखें)। संकल्पनात्मक रूप से, हां, ऑब्जेक्ट केवल पढ़ने के लिए है, इसलिए इसे स्पष्ट रूप से चिह्नित करना है या नहीं, इस पर निर्भर करता है कि क्या आप इस तथ्य से दस्तावेज करते हैं कि यह IBOutlet है।

अद्यतन: पॉल.s की टिप्पणी ने मुझे त्वरित परीक्षण करने के लिए प्रेरित किया।मैंने UIView सबक्लास बनाया है जो alloc, retain, release, और autorelease कॉल लॉग करता है, इसे एक निब में एक उदाहरण फंस गया, और ऐप को एक संपत्ति के माध्यम से IBOutlet प्रतिनिधि दिया।

हाथ से संदर्भ गिनती गतिविधि को टैली करना, उदाहरण (readwrite, assign) पर शुद्ध 0 गिनती के साथ आया था। यह संपत्ति +1 थी जब संपत्ति को अनुशंसित तरीके से घोषित किया गया था, (readwrite, retain), और जब यह (readonly, assign) था। यह सब अपेक्षा के मुकाबले बहुत अधिक है - जब यह (readwrite, assign) है, तो कनेक्शन सेट करने के लिए असाइनिंग सेटर का उपयोग किया जाता है, और कोई बनाए रखा नहीं जाता है। जब यह readonly है, तो कनेक्शन तंत्र अपने स्वयं के बनाए रखने पर वापस आ जाता है।

सबसे दिलचस्प बात यह है कि जब मैंने इस दृश्य के पृष्ठभूमि रंग को (readwrite, assign) (यानी, जब इसे संभवतया हटा दिया गया था) घोषित करके ऐप को क्रैश करने का प्रयास किया, तो मैंने retain पॉप अप पर एक अंतिम कॉल देखा।

मुझे लगता है कि यह क्या नीचे आता है: ऐप्पल की सिफारिश का पालन करें - वे जानते हैं कि दृश्यों के पीछे क्या चल रहा है, और (बग को छोड़कर) आपको गलत करने के लिए नहीं जा रहे हैं।

(दूर जाने की एक और बात यह है कि, हमेशा के रूप में, पूर्ण संदर्भ गणनाओं के बारे में चिंता करना बहुत उपयोगी नहीं होगा - दो दर्जन कॉल के दौरान गिनती एक बिंदु पर 6 तक पहुंच गई retain और release करने के लिए - तुम सिर्फ बरकरार रखे हुए है और विज्ञप्ति कि आप सीधे कारण के बारे में चिंता करने की जरूरत)


बेशक

*, इस एआरसी के तहत बदल जाता है।। मैंने जो जानकारी दी है वह अपने अध्याय के "विरासत पैटर्न" खंड में है। एआरसी के तहत, IBOutlets के लिए weak होने की सिफारिश है जब तक कि वे शीर्ष-स्तर न हों, इस स्थिति में वे strong होना चाहिए। इस तरह से ऐसा करने का मतलब है कि आप खुद को बनाए रखने के लिए दृश्य पदानुक्रम (उनके सबव्यूज़ को बनाए रखने के विचार) पर भरोसा कर रहे हैं।

+0

'क्या आउटलेट को बनाए रखने या असाइन करने के रूप में घोषित किया गया है, दूसरी तरफ ऑब्जेक्ट ऑब्जेक्ट के स्वामित्व वाले ऑब्जेक्ट के स्वामित्व में है (यह इतना स्पष्ट नहीं है) यह केवल तभी होता है जब यह' रीडोनली 'पर सेट हो? यदि यह '(असाइन, रीडराइट) था 'तो निश्चित रूप से गैर-रखरखाव सेटटर का उपयोग किया जाएगा और' रखरखाव 'नहीं लिया जाएगा? - मैं केवल इसलिए उल्लेख करता हूं क्योंकि यह आपके उत्तर का एकमात्र हिस्सा है जो थोड़ा अस्पष्ट था –

+0

मुझे ऐसा लगता है ... यह निश्चित रूप से ऐसा लगता है। –

+2

@ पॉल.s: मेरा अपडेट देखें - मैंने संदर्भ गतिविधि को हाथ से गिनने का फैसला किया और परिणाम, मुझे लगता है, निर्देशक। –

2

मुझे लगता है कि अगर आप गुण के बजाय IBOutlet उदाहरण चर बनाते हैं तो वह Xcode अभी भी स्वचालित रूप से iOS एप्लिकेशन के लिए रिलीज के दशक में dealloc आदि Xcode पैदा करेगा हमेशा कि क्या इसका सही है या नहीं IBOutlet के लिए विज्ञप्ति बनाने के लिए लगता है एप्पल के साथ एक बग सूचना दी है।

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

+0

आप सार्वजनिक इंटरफ़ेस में '@property (nonatomic, readonly)' और कक्षा विस्तार में '@property (nonatomic) IBOutlet' घोषित कर सकते हैं। –

संबंधित मुद्दे