2011-12-21 14 views
67

बस कि मैं यह अधिकार मिल गया सुनिश्चित करना चाहते हैं:एआरसी - __unsafe_unretained का अर्थ?

  1. मैं __unsafe_unretain वस्तुओं है कि मेरा अधिकार नहीं है की जरूरत है?
  2. यदि कोई ऑब्जेक्ट __unsafe_unretained है तो मुझे में assign का उपयोग करने की आवश्यकता है? क्या इसका मतलब यह है कि ऑब्जेक्ट को बनाए रखा नहीं गया है, और केवल उस ऑब्जेक्ट को संदर्भित करता है जिसे मैं असाइन करता हूं?
  3. प्रतिनिधियों को छोड़कर मैं इसका उपयोग कब करना चाहूंगा?
  4. क्या यह एक एआरसी चीज है या इससे पहले उपयोग में था?

उत्तर

172

LLVM संकलक 3.0 चार नए स्वामित्व क्वालिफायर परिचय देता है। पहले तीन एआरसी के बाहर भी उपलब्ध हैं, the specification के अनुसार।

जैसा कि यहोशू इंगित करता है, डिफ़ॉल्ट रूप से सभी पॉइंटर्स एआरसी के तहत __strong होने के लिए निहित हैं। इसका अर्थ यह है कि जब किसी ऑब्जेक्ट को उस पॉइंटर को असाइन किया जाता है, तब तक यह तब तक बनाए रखा जाता है जब तक कि पॉइंटर इसका संदर्भ न दे। यह ज्यादातर चीजों के लिए ठीक है, लेकिन यह चक्र को बनाए रखने की संभावना को खोलता है, जैसा कि मैंने अपने उत्तर here में वर्णित किया है। उदाहरण के लिए, यदि आपके पास कोई ऑब्जेक्ट है जिसमें एक आवृत्ति चर के रूप में कोई अन्य ऑब्जेक्ट है, लेकिन उस दूसरे ऑब्जेक्ट के पहले प्रतिनिधि को इसके प्रतिनिधि के रूप में एक मजबूत लिंक है, तो दो ऑब्जेक्ट्स कभी रिलीज़ नहीं होंगे।

इस कारण से __unsafe_unretained और __weak क्वालीफायर मौजूद हैं। उनका सबसे आम उपयोग प्रतिनिधियों के लिए है, जहां आप weak या unsafe_unretained विशेषता (assign प्रभावी रूप से) के साथ उस प्रतिनिधि के लिए एक संपत्ति परिभाषित करेंगे, और उसके बाद संबंधित उदाहरण चर को __weak या __unsafe_unretained के साथ चिह्नित करके मिलान करें। इसका मतलब यह है कि प्रतिनिधि उदाहरण चर पहले भी ऑब्जेक्ट पर वापस आ जाएगा, लेकिन यह उस वस्तु को बनाए रखने का कारण नहीं बनता है, इस प्रकार बनाए रखने वाले चक्र को तोड़ देता है और दोनों वस्तुओं को रिहा कर दिया जाता है।

प्रतिनिधियों से परे, यह आपके कोड में मौजूद किसी अन्य बनाए रखने वाले चक्र को तोड़ने के लिए उपयोगी है। मददगार रूप से, लीक्स उपकरण में अब एक चक्र दृश्य शामिल है, जो दिखाता है कि यह आपके ग्राफ़िकल तरीके से आपके अनुप्रयोग में खोज चक्रों को बनाए रखता है।

__unsafe_unretained और __weak दोनों वस्तुओं के प्रतिधारण को रोकने, लेकिन थोड़ा अलग तरीकों से रोकें। __weak के लिए, किसी ऑब्जेक्ट का पॉइंटर उस ऑब्जेक्ट को हटाने के लिए nil में परिवर्तित हो जाएगा, जो बहुत सुरक्षित व्यवहार है।जैसा कि इसके नाम से तात्पर्य है, __unsafe_unretained उस स्मृति को इंगित करना जारी रखेगा जहां ऑब्जेक्ट था, इसे हटाए जाने के बाद भी। इससे उस विलुप्त वस्तु तक पहुंचने के कारण क्रैश हो सकता है।

तब आप कभी भी __unsafe_unretained का उपयोग क्यों करेंगे? दुर्भाग्यवश, __weak केवल आईओएस 5.0 और शेर के लिए तैनाती लक्ष्य के रूप में समर्थित है। यदि आप आईओएस 4.0 और हिम तेंदुए पर वापस लक्षित करना चाहते हैं, तो आपको __unsafe_unretained क्वालीफायर का उपयोग करना होगा, या माइक ऐश के MAZeroingWeakRef जैसे कुछ का उपयोग करना होगा।

+2

और निश्चित रूप से '__unsafe_unretained' हो सकता है 'एनएसएसटींग' स्थिरांक के सी सरणी को परिभाषित करने के लिए उपयोगी और जैसे, उदाहरण के लिए 'एनएसएसटींग __unsafe_unretained * myStrings = {@" Foo ", @" बार ", @" बाज़ ", शून्य};' – jlehr

+0

महान उत्तर के लिए धन्यवाद। जब मैं __unsafe_unretained का उपयोग करता हूं तो आईओएस डिवाइस के ओएस 5 होने पर इसे _weak के रूप में संदर्भित करेगा? या यह xCode पर संकलन समय पर सेट है? – shannoga

+1

@ शन्नोगा - नहीं, आपको उन प्रकार के पॉइंटर्स का उपयोग करने के लिए मैन्युअल रूप से '__weak' को क्वालीफायर के रूप में निर्दिष्ट करना होगा। आप अभी भी पूरी तरह से 5.0 लक्ष्य के साथ '__unsafe_unretained' का उपयोग कर सकते हैं और यह' __weak' जैसा व्यवहार नहीं करेगा। यदि आप कुछ ऐसा चाहते हैं जो आपके लक्ष्य का समर्थन करता है या नहीं, तो आप दो मॉडलों के बीच स्विच करेंगे, जैसा कि मैं यहां सुझाता हूं, आप एक कंपाइलर-विशिष्ट परिभाषा का उपयोग कर सकते हैं: http://stackoverflow.com/a/8594878/19679 –

4
  1. नहीं, आप भी weak वस्तुओं है कि आपकी नहीं है के लिए इस्तेमाल कर सकते हैं।
  2. नहीं, आप संपत्ति पर unsafe_unretained का भी उपयोग कर सकते हैं।
  3. मेरी समझ यह है कि unsafe_unretained आइटम weak की तरह हैं, जब उन्हें आइटम जारी होने पर इंगित करने की अतिरिक्त सुरक्षा के बिना (और इसके साथ चलने वाले ओवरहेड) को साफ़ करने की अतिरिक्त सुरक्षा के बिना।
  4. यह पूरी तरह से एक एआरसी चीज है।
+0

असल में, अजीब रूप से पर्याप्त, 'unsafe_unretained' iVars, रनटाइम पर सेट होने पर,' मजबूत 'की तरह व्यवहार करता है, जो मुझे विश्वास दिलाता है कि' unsafe_unretained' बस एक कंपाइलर संकेत है, जबकि कमजोर नहीं है। यहां अधिक जानकारी: http://stackoverflow.com/questions/11621028/discovering-at-runtime-wich-of-a-class-instance-variables-are-declared-weak#comment15389310_11621028 –

4

__unsafe_unretained एआरसी से पहले किसी ऑब्जेक्ट का डिफ़ॉल्ट संग्रहण समान था। एआरसी के साथ डिफ़ॉल्ट अब __strong है जिसका अर्थ है कि जब तक आपका संदर्भ दायरे से बाहर नहीं जाता है तब तक इसका संदर्भ होता है। __strong, __autoreleasing, __unsafe_unretained, और __weak:

1

__unsafe_unretained पर एक और अवलोकन: मुझे डिवाइस पर अपने ऐप में क्रैश हो गया है और सिम्युलेटर पर सिम्युलेटर पर __unsafe_unretained के रूप में घोषित नहीं किया गया है! हां, यह एआरसी माइग्रेशन से कोड में एक बग था, लेकिन यह पहली बार था जब मैंने डिवाइस और सिम्युलेटर के बीच इतना अंतर देखा।