5

में एक UIViewController का रिलीज/निपटान जैसा कि मैं इसे समझता हूं, हमें मोनो टच में उनके साथ निपटने के दौरान हमारे कोको वस्तुओं के संदर्भों को रखने की आवश्यकता है। इसका कारण यह है कि ओबीजेसी रनटाइम अभी भी ऑब्जेक्ट्स के संदर्भ रख सकता है, और यदि हमारे पास उन पर "मोनो टच संदर्भ" नहीं है, तो वे कचरा इकट्ठा कर सकते हैं, जिसके परिणामस्वरूप ओबीजेसी रनटाइम उन्हें एक्सेस करने की कोशिश करता है जैसे EXC_BAD_ACCESSमोनो टच

कहें, हमारे पास दो UIViewController उपclasses, VC1 और VC2 हैं। यदि उपयोगकर्ता वीसी 1 पर एक बटन पर क्लिक करता है, तो यूआई वीसी 2 पर नेविगेट करता है, और उपयोगकर्ता आगे और आगे नेविगेट कर सकता है। यदि मैं हर बार जब उपयोगकर्ता इसे नेविगेट करता है तो वीसी 2 का नया उदाहरण बनाते हैं, तो पुराने उदाहरणों के संदर्भ गुम हो जाते हैं, इसलिए वे कचरा इकट्ठा होते हैं और ऐप अगली बार didReceiveMemoryWarning को UIViewControllers के लिए प्रचारित किया जाता है।

मैं पुराने संदर्भ कैसे जारी कर सकता हूं, इसलिए मुझे हर बार वीसी 2 के समान उदाहरण का उपयोग करने की आवश्यकता नहीं है? Dispose पर्याप्त नहीं लग रहा था।

उत्तर

6

जैसा कि मैं इसे समझता हूं, हमें मोनो टच में उनके साथ निपटने के दौरान हमारे कोको वस्तुओं के संदर्भों को रखने की आवश्यकता है।

काफी नहीं। मोनो टच प्रबंधित उदाहरण देशी उदाहरणों का संदर्भ रखेंगे। जब तक प्रबंधित उदाहरण मूल उदाहरण जीवित रहेगा (क्योंकि वे संदर्भित हैं और मोनो टच इसका संदर्भ जारी नहीं करेगा)।

IOW MonoTouch के लिए संदर्भ धारण करने के लिए अपनी जरूरत उदाहरणों जब तक उनके देशी भाग के रूप में की आवश्यकता होती है में कामयाब रहे।

इस का कारण यह है कि ObjC क्रम अभी भी, वस्तुओं ... वे कचरा एकत्र किया जा सकता के लिए संदर्भ पैदा हो सकती हैं

मूल निवासी (वस्तुनिष्ठ सी) उदाहरणों संदर्भ में गिने जाते हैं, नहीं कचरा एकत्र । मूल उदाहरण तब तक जारी नहीं किए जाएंगे जब तक उनके संदर्भ संख्या पहुंच 0 (जो तब नहीं होगा जब संबंधित प्रबंधित उदाहरण मौजूद है);

इसके अलावा मूल उदाहरण अन्य मूल उदाहरणों के संदर्भ भी रख सकते हैं। प्रत्येक देशी उदाहरणों के साथ प्रबंधित उदाहरण नहीं है।

जिसके परिणामस्वरूप ओबीजेसी रनटाइम उन्हें एक्सेस करने की कोशिश करता है जैसे EXC_BAD_ACCESS में परिणाम होता है।

ऐसा नहीं होगा, कम से कम इस तरह से नहीं। ओटीओएच आपको यह बताना मुश्किल है कि आपके मामले में क्या हो रहा है (कोड और/या दुर्घटनाओं को देखे बिना)।

मैं संदिग्ध आप निपटान कर रहे हैं (स्वयं या नहीं) अपने कामयाब उदाहरणों से पहले वे अपनी नौकरी पूरी कर ली है। यहाँ एक सरलीकृत क्या हो सकता है की है:

  • आपके द्वारा बनाए गए एक कामयाब MT.X इंस्टेंस (उदा एक UIView);
  • यह देशी एक्स (मूल संदर्भ संख्या == 1) बनाता है और संदर्भित करता है;
  • आप किसी ईवेंट को ओवरराइड करते हैं (या एक प्रतिनिधि जोड़ें ...) MT.X पर 'ViewWillUnload' (जो मूल रूप से भी मौजूद है);
  • आप एमटी.एक्स उदाहरण को किसी अन्य (प्रबंधित) उदाहरण में निर्दिष्ट करते हैं, उदा। एक UIViewController;
  • देशीUIViewControllerदेशी एक्स के लिए एक संदर्भ जोड़ देगा (देशी संदर्भ गिनती == 2);
  • आवेदन happilly कार्यान्वित ...
  • आप MT.X उदाहरण के लिए एक संदर्भ होने को रोकने के (जैसे null चर या एक अलग उदाहरण सेट);
  • वहाँ MT.X के लिए कोई संदर्भ है, क्योंकि अब और कचरा कलेक्टर निपटान होगा कामयाब उदाहरण, Dispose बुला जो संदर्भ कम हो जाएगा देशी एक्स (देशी संदर्भ गिनती == 1)। लेकिन देशी उदाहरण मुक्त नहीं किया जाएगा क्योंकि दृश्य नियंत्रक द्वारा अभी भी संदर्भित किया गया है (0 नहीं);
  • UIViewController ऐसा कुछ करता है जो ट्रिगर करता है, मूल रूप से, X.ViewWillUnload (उदा। यह एक नया UIView लोड करने का प्रयास करता है);
  • X के बाद से अभी भी मूल रूप से मौजूद है (संदर्भ गिनती == 1) यह ViewWillUnload जो वापस करने के लिए जाना उदाहरण कामयाब रहे ... कि था निपटारा करने की कोशिश करेंगे है कॉल करेंगे।

इस समस्या का समाधान सुनिश्चित सुनिश्चित करने के लिए आप निपटान नहीं कर रहे हैं कामयाब उदाहरण उनके देशी हिस्सा जब तक अपने काम को पूरा कर लिया है।

+1

धन्यवाद, लेकिन मुझे यकीन है कि मेरे पास कोई संदर्भ शेष नहीं है। 'वीसी 2' संदर्भ का एकमात्र प्रबंधित चीज मेरा 'वीसी 1' उदाहरण है, इसलिए जब मैं इस उदाहरण को रद्द कर रहा हूं, मूल 'वीसी 2' उदाहरण पर संदर्भ गणना 0 होना चाहिए। लेकिन ऐसा लगता है जैसे आईओएस संदर्भ का पालन कर रहा है 'didReceiveMemoryWarning' संदेशों के वितरण के लिए नियंत्रक, क्योंकि जैसे ही 'didReceiveMemoryWarning' संदेश होता है, मेरा ऐप क्रैश हो जाता है। – cheeesus

+0

आपके पास ** प्रबंधित ** संदर्भ नहीं हैं लेकिन आपके पास ** मूल ** संदर्भ शेष (उनके या उनके माता-पिता के बीच) हो सकते हैं। इससे पहले कि आप सुनिश्चित हों कि उनका जीवन चक्र (मूल पक्ष) खत्म हो गया है, इससे पहले कि आप एक डिस्पोजेड (प्रबंधित) उदाहरण में वापस कॉल कर सकें, आपको उन्हें (प्रबंधित पक्ष) को कम नहीं करना चाहिए। यदि आपके पास एक छोटा परीक्षण केस है (या निकाल सकता है) तो एक बग रिपोर्ट @ http://bugzilla.xamarin.com खोलें और हम कोड की समीक्षा करेंगे। – poupou

+0

ठीक है, मैं इसे अलग करने की कोशिश कर रहा हूं। आपकी सहायता के लिए धन्यवाद. – cheeesus

1

मेरे पास मेरे ऐप में एक ही स्थिति है और जीसी ऑब्जेक्ट्स को सही तरीके से एकत्र करता है। दूसरे शब्दों में, मैंने किसी वीसी के संदर्भ में बस एक समस्या का अनुभव नहीं किया और जीसी को आराम करने दिया।

हालांकि, जब आप Dispose विधि के लिए बुलाते हैं तो मुझे समस्याएं होती हैं। ऐसा लगता है कि हमें इसे मैन्युअल रूप से नहीं करना चाहिए। इसके बजाय हमें वस्तुओं को इकट्ठा करने और अपने संसाधनों को मुक्त करने के लिए जीसी की प्रतीक्षा करनी चाहिए। बेस NSObject कक्षा के पास इसके अंतिमकरण में Dispose पर कॉल है, इसलिए सभी अप्रबंधित संसाधनों को ऑब्जेक्ट पर एकत्रित किया जाएगा।

आप रूट वीसी के DidReceiveMemoryWarning विधि में से कुछ में GC.Collect भी कॉल कर सकते हैं।

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