क्या हम हमेशा स्विफ्ट में बंद होने के अंदर [प्रसिद्ध स्वयं] का उपयोग करते हैं


467

डब्ल्यूडब्ल्यूडीसी 2014 सत्र 403 इंटरमीडिएट स्विफ्ट और ट्रांसक्रिप्ट में , निम्नलिखित स्लाइड थी

यहाँ छवि विवरण दर्ज करें

उस स्थिति में स्पीकर ने कहा, अगर हम [unowned self]वहां उपयोग नहीं करते हैं, तो यह मेमोरी लीक होगा। क्या इसका मतलब है कि हमें हमेशा [unowned self]अंदर से बंद करना चाहिए ?

स्विफ्ट वेदर ऐप के ViewController.swift की लाइन 64 पर , मैं उपयोग नहीं करता [unowned self]। लेकिन मैं कुछ @IBOutletएस self.temperatureऔर जैसे का उपयोग करके यूआई को अपडेट करता हूं self.loadingIndicator। यह ठीक हो सकता है क्योंकि @IBOutletमेरे द्वारा परिभाषित सभी s हैं weak। लेकिन सुरक्षा के लिए, क्या हमें हमेशा उपयोग करना चाहिए [unowned self]?

class TempNotifier {
  var onChange: (Int) -> Void = {_ in }
  var currentTemp = 72
  init() {
    onChange = { [unowned self] temp in
      self.currentTemp = temp
    }
  }
}

छवि लिंक टूट गया है
डैनियल गोमेज़ रिको

@ DanielG.R। धन्यवाद, मैं इसे देख सकता हूं। i.stack.imgur.com/Jd9Co.png
जेक लिन

2
जब तक मैं गलत नहीं हूँ, स्लाइड में दिया गया उदाहरण गलत onChangeहै - एक [weak self]बंद होना चाहिए , क्योंकि यह एक सार्वजनिक (आंतरिक रूप से, लेकिन अभी भी) संपत्ति है, इसलिए एक अन्य वस्तु को प्राप्त कर सकते हैं और बंद कर सकते हैं, TempNotifier ऑब्जेक्ट को चारों ओर रखते हुए (अनिश्चित रूप से यदि उपयोग करने वाली वस्तु को onChangeतब तक बंद नहीं होने दिया जाता जब तक कि यह TempNotifierचला नहीं जाता, अपने स्वयं के कमजोर रेफरी के माध्यम से TempNotifier) । अगर var onChange …थे private var onChange …तो [unowned self]सही होंगे। मैं हालांकि इस बारे में 100% निश्चित नहीं हूँ; अगर मैं गलत हूं तो कोई मुझे सही करे।
स्लिप डी। थॉम्पसन जूल

@Jake लिन `var onChange: (Int) -> Void = {}` घुंघराले ब्रेसिज़ एक खाली क्लोजर का प्रतिनिधित्व करते हैं? उसी के साथ एक खाली सरणी को परिभाषित करने में है []? मुझे Apple डॉक्स में स्पष्टीकरण नहीं मिला।
बिबसी

@bibscy हाँ, {}खाली क्लोज़र (क्लोज़र का उदाहरण) डिफ़ॉल्ट के रूप में है (कुछ भी नहीं करता है), (Int) -> Voidक्लोज़र परिभाषा है।
जेक लिन

जवाबों:


871

नहीं, निश्चित रूप से ऐसे समय हैं जहां आप उपयोग नहीं करना चाहेंगे [unowned self]। कभी-कभी आप स्वयं को पकड़ने के लिए बंद करना चाहते हैं ताकि यह सुनिश्चित हो सके कि जब तक क्लोजर कहा जाता है तब तक यह चारों ओर है।

उदाहरण: एक एसिंक्रोनस नेटवर्क अनुरोध बनाना

यदि आप एक एसिंक्रोनस नेटवर्क अनुरोध कर रहे हैं, तो आप चाहते हैं कि selfजब अनुरोध समाप्त हो जाए तो उसे बनाए रखने के लिए बंद कर दें । वह वस्तु अन्यथा निपटा दी गई हो, लेकिन आप अभी भी अनुरोध को पूरा करने में सक्षम होना चाहते हैं।

कब इस्तेमाल करें unowned selfयाweak self

केवल समय जहां आप वास्तव में उपयोग करना चाहते हैं [unowned self]या [weak self]जब आप एक मजबूत संदर्भ चक्र बनायेंगे । एक मजबूत संदर्भ चक्र तब होता है जब स्वामित्व का एक लूप होता है जहां वस्तुएं एक-दूसरे (शायद तीसरे पक्ष के माध्यम से) के मालिक होती हैं और इसलिए उन्हें कभी नहीं निपटा जाएगा क्योंकि वे दोनों यह सुनिश्चित कर रहे हैं कि एक-दूसरे के आसपास रहना।

एक बंद होने के विशिष्ट मामले में, आपको बस यह महसूस करने की आवश्यकता है कि कोई भी चर जो इसके अंदर संदर्भित है, बंद होने से "स्वामित्व" हो जाता है। जब तक बंद होने के आसपास है, तब तक उन वस्तुओं को आसपास रहने की गारंटी दी जाती है। उस स्वामित्व को रोकने का एकमात्र तरीका, [unowned self]या करना है [weak self]। इसलिए यदि कोई वर्ग एक बंद का मालिक है, और वह बंद उस वर्ग के एक मजबूत संदर्भ को पकड़ता है, तो आपके पास बंद और वर्ग के बीच एक मजबूत संदर्भ चक्र है। इसमें यह भी शामिल है कि अगर क्लास कुछ ऐसा है जो क्लोजर का मालिक है।

विशेष रूप से वीडियो से उदाहरण में

स्लाइड पर उदाहरण में, सदस्य चर के TempNotifierमाध्यम से बंद होने का मालिक है onChange। अगर वे घोषित नहीं किया था selfके रूप में unowned, बंद भी खुद हैं selfएक मजबूत संदर्भ चक्र का निर्माण।

unownedऔर के बीच अंतरweak

के बीच अंतर है unownedऔर weakयह weakएक वैकल्पिक के रूप में घोषित किया जाता है जबकि unownedऐसा नहीं है। यह घोषित करके weakआप इस मामले को संभाल सकते हैं कि यह किसी बिंदु पर बंद होने के अंदर शून्य हो सकता है। यदि आप एक unownedचर का उपयोग करने की कोशिश करते हैं जो शून्य होता है, तो यह पूरे कार्यक्रम को क्रैश कर देगा। इसलिए केवल तभी उपयोग करें unownedजब आप सकारात्मक हों कि चर हमेशा आसपास होगा जबकि क्लोजर आसपास है


1
नमस्ते। बहुत बढ़िया जवाब। मैं स्वयं को अज्ञात समझने के लिए संघर्ष कर रहा हूं। कमजोर का उपयोग करने का एक कारण केवल 'स्वयं एक वैकल्पिक बन जाना' है, मेरे लिए पर्याप्त नहीं है। मैं विशेष रूप से 'अज्ञात स्व' का उपयोग क्यों करना चाहता हूँ ' stackoverflow.com/questions/32936264/…

19
@robdashnash, अज्ञात स्वयं का उपयोग करने का लाभ यह है कि आपको एक वैकल्पिक को खोलना नहीं पड़ता है जो अनावश्यक कोड हो सकता है यदि आप डिजाइन द्वारा निश्चित रूप से जानते हैं, तो यह कभी भी शून्य नहीं होगा। अंततः, प्रसिद्ध स्वयं का उपयोग संक्षिप्तता के लिए किया जाता है और शायद भविष्य के डेवलपर्स के लिए एक संकेत के रूप में भी किया जाता है कि आप कभी भी शून्य मूल्य की उम्मीद नहीं करते हैं।
ड्रूग

77
एक [weak self]एसिंक्रोनस नेटवर्क अनुरोध में उपयोग करने के लिए एक मामला , एक दृश्य नियंत्रक में है जहां उस अनुरोध का उपयोग दृश्य को पॉप्युलेट करने के लिए किया जाता है। यदि उपयोगकर्ता पीछे हट जाता है, तो हमें अब दृश्य को देखने की आवश्यकता नहीं है, और न ही हमें दृश्य नियंत्रक के संदर्भ की आवश्यकता है।
डेविड जेम्स

1
weakसंदर्भ nilतब भी सेट किए जाते हैं जब ऑब्जेक्ट को हटा दिया जाता है। unownedसंदर्भ नहीं हैं।
BergQuester

1
मैं थोड़ा असमंजस में हूँ। unownedका उपयोग non-Optionalतब किया जाता है, जबकि हमारे weakलिए उपयोग किया जाता है या ? OptionalselfOptionalnon-optional
मुहम्मद नायब

193

अपडेट 11/2016

मैंने इस उत्तर को विस्तारित करने के लिए (एआरसी क्या करता है, यह समझने के लिए एसआईएल में देख) पर एक लेख लिखा था, इसे यहां देखें

मूल उत्तर

पिछले जवाब वास्तव में सीधे नियम नहीं देते हैं कि कब एक का उपयोग करना चाहिए और क्यों, इसलिए मुझे कुछ चीजें जोड़ने दें।

विख्यात या कमज़ोर चर्चा चर के जीवनकाल के एक सवाल को उबालती है और इसे बंद करने वाला संदर्भ।

स्विफ्ट कमजोर बनाम अज्ञात

परिदृश्य

आपके पास दो संभावित परिदृश्य हो सकते हैं:

  1. क्लोजर में वैरिएबल का एक ही जीवनकाल होता है, इसलिए क्लोजर केवल तब तक पहुंच योग्य होगा जब तक कि वैरिएबल उपलब्ध नहीं होगा । चर और बंद का जीवनकाल समान होता है। इस मामले में आपको संदर्भ को अज्ञात घोषित करना चाहिए । एक सामान्य उदाहरण [unowned self]छोटे क्लोजर के कई उदाहरणों में उपयोग किया जाता है जो अपने माता-पिता के संदर्भ में कुछ करते हैं और जिसे कहीं और संदर्भित नहीं किया जाता है, वे अपने माता-पिता को पसंद नहीं करते हैं।

  2. बंद जीवनकाल चर में से एक से स्वतंत्र है, बंद को तब भी संदर्भित किया जा सकता है जब चर अब उपलब्ध नहीं है। इस मामले में आपको संदर्भ को कमजोर घोषित करना चाहिए और यह सत्यापित करना चाहिए कि इसे इस्तेमाल करने से पहले शून्य न करें (इसे दबाएं नहीं)। इसका एक सामान्य उदाहरण यह है कि [weak delegate]आप पूरी तरह से असंबंधित (आजीवन-वार) प्रतिनिधि ऑब्जेक्ट को बंद करने के कुछ उदाहरणों में देख सकते हैं।

वास्तविक उपयोग

तो, जो आपको वास्तव में सबसे अधिक बार उपयोग करना चाहिए?

ट्विटर से जो ग्रॉफ को उद्धृत करते हुए :

प्रख्यात तेज है और अपरिवर्तनीयता और गैर-अपनाने की अनुमति देता है।

यदि आपको कमजोर की जरूरत नहीं है, तो इसका उपयोग न करें।

आपको यहां अनियोजित *आंतरिक कामकाज के बारे में अधिक जानकारी मिलेगी ।

* आमतौर पर यह भी कहा जाता है कि अनौपचारिक (सुरक्षित) के रूप में यह इंगित करने के लिए कि रनटाइम चेक (अमान्य संदर्भों के लिए दुर्घटना की ओर ले जाते हैं) को अज्ञात संदर्भ तक पहुँचने से पहले किया जाता है।


26
मैं तोते के स्पष्टीकरण को सुनकर थक गया हूं "सप्ताह का उपयोग करें यदि आत्म शून्य हो सकता है, तो बिना उपयोग किए जब यह कभी भी शून्य नहीं हो सकता है"। ठीक है हम मिल गए - यह एक लाख बार सुना! यह उत्तर वास्तव में गहरा खोदता है जब स्वयं सादे अंग्रेजी में शून्य हो सकता है, जो सीधे ओपी के प्रश्न का उत्तर देता है। इस बेहतरीन व्याख्या के लिए धन्यवाद !!
TruMan1

धन्यवाद @ TruMan1, मैं वास्तव में इस पर एक पोस्ट लिख रहा हूं जो जल्द ही मेरे ब्लॉग पर समाप्त हो जाएगा, एक लिंक के साथ उत्तर को अपडेट करेगा।
अम्बर्टो रायमंडी

1
अच्छा जवाब, बहुत व्यावहारिक। मैं अपने प्रदर्शन के कुछ संवेदनशील कमजोर संस्करणों को अभी तक बंद करने के लिए प्रेरित हूं।
original_username

"बंद जीवनकाल चर में से एक से स्वतंत्र है" क्या आपके पास यहां एक टाइपो है?
हनी

1
यदि एक बंद को हमेशा माता-पिता की वस्तु के समान जीवनकाल होता है, तो क्या वस्तु को नष्ट होने पर संदर्भ गणना को ध्यान नहीं दिया जाएगा? आप केवल इस स्थिति में 'स्वयं' का उपयोग अनजाने या कमजोर से परेशान करने के बजाय क्यों नहीं कर सकते?
लीजेंडलॉग्रफी

105

मैंने सोचा कि मैं विशेष रूप से एक दृश्य नियंत्रक के लिए कुछ ठोस उदाहरण जोड़ूंगा। स्टैक ओवरफ्लो पर न केवल यहां कई स्पष्टीकरण, वास्तव में अच्छे हैं, लेकिन मैं वास्तविक दुनिया के उदाहरणों के साथ बेहतर काम करता हूं (@drewag ने इस पर अच्छी शुरुआत की थी):

  • यदि आपके पास नेटवर्क अनुरोधों के उपयोग से प्रतिक्रिया को संभालने के लिए एक बंद है weak, क्योंकि वे लंबे समय तक रहते हैं। अनुरोध पूरा होने से पहले व्यू कंट्रोलर बंद हो सकता है इसलिए selfक्लोजर कहे जाने पर मान्य ऑब्जेक्ट की ओर इशारा नहीं करता है।
  • यदि आपके पास बंद है जो एक बटन पर एक घटना को संभालता है। ऐसा unownedइसलिए हो सकता है क्योंकि जैसे ही व्यू कंट्रोलर चला जाता है, बटन और किसी भी अन्य आइटम से संदर्भित हो सकता selfहै उसी समय चला जाता है। क्लोजर ब्लॉक भी उसी समय चला जाएगा।

    class MyViewController: UIViewController {
          @IBOutlet weak var myButton: UIButton!
          let networkManager = NetworkManager()
          let buttonPressClosure: () -> Void // closure must be held in this class. 
    
          override func viewDidLoad() {
              // use unowned here
              buttonPressClosure = { [unowned self] in
                  self.changeDisplayViewMode() // won't happen after vc closes. 
              }
              // use weak here
              networkManager.fetch(query: query) { [weak self] (results, error) in
                  self?.updateUI() // could be called any time after vc closes
              }
          }
          @IBAction func buttonPress(self: Any) {
             buttonPressClosure()
          }
    
          // rest of class below.
     }

17
यह एक और अधिक upvotes की जरूरत है। दो ठोस उदाहरण दिखाते हैं कि व्यू कंट्रोलर के जीवन काल के बाहर एक बटन प्रेस क्लोजर कैसे मौजूद नहीं होगा, और इसलिए अनजाने का उपयोग कर सकते हैं, लेकिन अधिकांश नेटवर्क कॉल जो अपडेट यूआई को कमजोर करने की आवश्यकता होती है।
टिम फूक्वा

2
तो बस स्पष्ट करने के लिए, क्या हम हमेशा एक बंद ब्लॉक में स्वयं को कॉल करते समय अज्ञात या कमजोर का उपयोग करते हैं? या कोई ऐसा समय है, जहां हम कमजोर / गैरकानूनी नहीं कहेंगे? यदि हां, तो क्या आप इसके लिए एक उदाहरण प्रदान कर सकते हैं?
ल्यूक

बहुत बहुत धन्यवाद।
शॉन बेक

1
इससे मुझे [कमज़ोर आत्म] और [नामी स्व] के बारे में अधिक गहरी समझ मिली, बहुत बहुत धन्यवाद @ पोज़!
टॉमी

यह भी खूब रही। क्या होगा यदि मेरे पास एक एनीमेशन है जो उपयोगकर्ता इंटरैक्शन पर आधारित है, लेकिन खत्म होने में थोड़ा समय लगता है। और फिर उपयोगकर्ता दूसरे व्यू-कॉन्ट्रोलर के पास जाता है। मुझे लगता है कि उस मामले में मुझे अभी भी सही के weakबजाय उपयोग करना चाहिए unowned?
हनी

67

यदि स्वयं को बंद उपयोग [कमजोर स्वयं] में शून्य किया जा सकता है ।

यदि स्वयं को बंद करने के उपयोग में शून्य नहीं होगा [अज्ञात स्व]

Apple स्विफ्ट प्रलेखन में छवियों का एक बड़ा भाग है , जो मजबूत , कमजोर , और बंद में अज्ञात का उपयोग करने के बीच के अंतर को समझाता है :

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html


50

यहाँ Apple डेवलपर मंच से शानदार उद्धरण स्वादिष्ट विवरण का वर्णन किया गया है:

unownedबनाम unowned(safe)बनामunowned(unsafe)

unowned(safe)एक गैर-मालिकाना संदर्भ है जो उस पहुंच पर जोर देता है जो वस्तु अभी भी जीवित है। यह एक कमजोर वैकल्पिक संदर्भ की तरह है जो x!हर बार इसे एक्सेस किए जाने के साथ अंतर्निहित है। एआरसी की unowned(unsafe)तरह __unsafe_unretainedहै - यह एक गैर-मालिकाना संदर्भ है, लेकिन कोई रनटाइम जांच नहीं है कि ऑब्जेक्ट अभी भी एक्सेस पर जीवित है, इसलिए झूलते हुए संदर्भ कचरा मेमोरी में पहुंच जाएंगे। वर्तमान unownedमें हमेशा एक पर्यायवाची है unowned(safe), लेकिन आशय यह है कि इसे बिल्ड्स unowned(unsafe)में ऑप्टिमाइज़ किया जाएगा -Ofastजब रनटाइम चेक अक्षम हो जाते हैं।

unowned बनाम weak

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

अद्यतन: आधुनिक स्विफ्ट में weakआंतरिक रूप से उसी तंत्र का उपयोग करता है जो unownedकरता है । इसलिए यह तुलना गलत है क्योंकि यह weakस्विफ्ट के साथ ऑब्जेक्टिव-सी की तुलना करती है unonwed

कारण

संदर्भों को 0 तक पहुँचाने के बाद स्मृति को जीवित रखने का क्या उद्देश्य है? यदि कोड विखंडित होने के बाद किसी अज्ञात संदर्भ का उपयोग करके ऑब्जेक्ट के साथ कुछ करने का प्रयास करता है तो क्या होता है?

स्मृति को जीवित रखा जाता है ताकि इसकी बरकरार गणना अभी भी उपलब्ध हो। इस तरह, जब कोई अज्ञात वस्तु के लिए एक मजबूत संदर्भ बनाए रखने का प्रयास करता है, तो रनटाइम जांच सकता है कि मजबूत संदर्भ गणना शून्य से अधिक है ताकि यह सुनिश्चित किया जा सके कि वस्तु को बनाए रखना सुरक्षित है।

ऑब्जेक्ट द्वारा रखे गए स्वयं के या अज्ञात संदर्भों का क्या होता है? क्या उनके जीवनकाल को वस्तु से तबाह कर दिया जाता है जब इसे विखंडित किया जाता है या उनकी स्मृति को तब तक बरकरार रखा जाता है जब तक कि वस्तु को अंतिम रूप से जारी किए जाने के बाद हटा दिया जाता है?

ऑब्जेक्ट के स्वामित्व वाले सभी संसाधनों को ऑब्जेक्ट के अंतिम मजबूत संदर्भ के जारी होते ही जारी किया जाता है, और इसके डिनिट को चलाया जाता है। विख्यात संदर्भ केवल मेमोरी को जीवित रखते हैं - हेडर से अलग संदर्भ काउंट के साथ, इसकी सामग्री कबाड़ है।

उत्साहित है, है ना?


38

यहाँ कुछ महान जवाब हैं। लेकिन हाल ही में परिवर्तन कैसे स्विफ्ट कमजोर संदर्भों को लागू करता है, हर किसी के कमजोर आत्म बनाम अज्ञात स्वयं उपयोग निर्णयों को बदलना चाहिए। इससे पहले, यदि आपको अज्ञात स्वयं का उपयोग करने के लिए सबसे अच्छे प्रदर्शन की आवश्यकता होती है, तो कमजोर स्वयं से बेहतर था, जब तक कि आप निश्चित हो सकते हैं कि स्वयं को कभी भी शून्य नहीं किया जाएगा, क्योंकि कमजोर स्वयं तक पहुँचने की तुलना में अज्ञात स्वयं तक पहुँचना बहुत तेज़ है।

लेकिन माइक ऐश ने प्रलेखित किया है कि स्विफ्ट ने साइड-टेबल का उपयोग करने के लिए कमजोर संस्करण के कार्यान्वयन को कैसे अपडेट किया है और यह कैसे कमजोर आत्म प्रदर्शन में काफी सुधार करता है।

https://mikeash.com/pyblog/friday-qa-2017-09-22-swift-4-weak-references.html

अब जबकि कमजोर स्वयं के लिए एक महत्वपूर्ण प्रदर्शन जुर्माना नहीं है, मेरा मानना ​​है कि हमें इसे आगे बढ़ाने के लिए डिफ़ॉल्ट होना चाहिए। कमजोर स्वयं का लाभ यह है कि यह एक वैकल्पिक है, जिससे इसे अधिक सही कोड लिखना आसान हो जाता है, यह मूल रूप से स्विफ्ट इतनी बड़ी भाषा है। आप सोच सकते हैं कि आप जानते हैं कि कौन सी स्थितियां स्वयं के उपयोग के लिए सुरक्षित हैं, लेकिन मेरा अनुभव बहुत सारे अन्य डेवलपर्स कोड की समीक्षा करने का है, सबसे अधिक नहीं। मैंने बहुत सारी दुर्घटनाएँ तय की हैं जहाँ गैर-कानूनी रूप से खुद को निपटाया गया था, आमतौर पर ऐसी स्थितियों में जहां एक नियंत्रक के बाद एक पृष्ठभूमि धागा पूरा होता है।

बग्स और क्रैश प्रोग्रामिंग के सबसे अधिक समय लेने वाले, दर्दनाक और महंगे हिस्से हैं। सही कोड लिखने और उनसे बचने की पूरी कोशिश करें। मैं इसे अनचाहे विकल्प को कभी भी मजबूर नहीं करने और कमजोर स्वयं के बजाय अनजाने स्वयं का उपयोग करने का नियम बनाने की सलाह देता हूं। आप कुछ भी नहीं खो देंगे समय बल को उजागर नहीं करते हैं और अज्ञात स्वयं वास्तव में सुरक्षित हैं। लेकिन आप क्रैश और बग्स को खोजने और डिबग करने के लिए कड़ी मेहनत को खत्म करने से बहुत कुछ हासिल करेंगे।


अपडेट के लिए धन्यवाद और आखिरी पैराग्राफ पर आमीन।
आदर्श वाक्य

1
इसलिए नए बदलावों के बाद क्या कभी ऐसा समय है जहां ए की weakजगह इस्तेमाल नहीं किया जा सकता है unowned?
हनी

4

Apple-doc के अनुसार

  • कमजोर संदर्भ हमेशा एक वैकल्पिक प्रकार के होते हैं, और स्वचालित रूप से शून्य हो जाते हैं, जब वे संदर्भ संदर्भित करते हैं।

  • यदि कैप्चर किया गया संदर्भ कभी शून्य नहीं होगा, तो इसे हमेशा एक कमजोर संदर्भ के बजाय एक अज्ञात संदर्भ के रूप में कैप्चर किया जाना चाहिए

उदाहरण -

    // if my response can nil use  [weak self]
      resource.request().onComplete { [weak self] response in
      guard let strongSelf = self else {
        return
      }
      let model = strongSelf.updateModel(response)
      strongSelf.updateUI(model)
     }

    // Only use [unowned self] unowned if guarantees that response never nil  
      resource.request().onComplete { [unowned self] response in
      let model = self.updateModel(response)
      self.updateUI(model)
     }

0

यदि उपरोक्त में से कोई भी समझ में नहीं आता है:

tl; डॉ

एक की तरह implicitly unwrapped optional, यदि आप यह गारंटी दे सकते हैं कि संदर्भ इसके उपयोग के बिंदु पर शून्य नहीं होगा, तो अज्ञात का उपयोग करें। यदि नहीं, तो आपको कमजोर का उपयोग करना चाहिए।

स्पष्टीकरण:

मैंने नीचे निम्नलिखित को पुनः प्राप्त किया: कमजोर अज्ञात लिंक । मैं जो इकट्ठा किया था, उससे अनजाने में आत्म शून्य नहीं हो सकता, लेकिन कमजोर स्वयं हो सकता है, और अनजाने में स्वयं को खतरे में डाल सकता है ... उद्देश्य-सी में कुछ बदनाम। आशा है ये मदद करेगा

"कमज़ोर कमजोर और अज्ञात संदर्भ समान व्यवहार करते हैं लेकिन समान नहीं हैं।"

विख्यात संदर्भ, कमजोर संदर्भों की तरह , संदर्भित की जा रही वस्तु की प्रतिधारण संख्या में वृद्धि नहीं करते हैं । हालाँकि, स्विफ्ट में, एक अज्ञात संदर्भ में वैकल्पिक नहीं होने का अतिरिक्त लाभ है । इससे उन्हें वैकल्पिक बंधन का सहारा लेने के बजाय प्रबंधन करना आसान हो जाता है । यह Implicitly Unwrapped Optionals के विपरीत नहीं है। इसके अलावा, अज्ञात संदर्भ गैर-शून्य हैंइसका मतलब यह है कि जब ऑब्जेक्ट को हटा दिया जाता है, तो यह पॉइंटर को शून्य नहीं करता है। इसका मतलब यह है कि कुछ मामलों में, अज्ञात संदर्भों का उपयोग, लटकने वाले बिंदुओं तक ले जा सकता है। आप के लिए वहाँ nerds है कि याद करते हैं उद्देश्य-सी दिनों की तरह मैं करता हूँ, अज्ञात संदर्भ असुरक्षित असुरक्षित संदर्भों के लिए नक्शा।

यह वह जगह है जहाँ यह थोड़ा भ्रमित हो जाता है।

कमजोर और अज्ञात संदर्भ, दोनों ही मायने नहीं रखते हैं।

इन दोनों का उपयोग चक्र को बनाए रखने के लिए किया जा सकता है। तो हम उनका उपयोग कब करते हैं ?!

Apple के डॉक्स के अनुसार :

“जब भी वह संदर्भ के लिए मान्य हो, तो अपने जीवनकाल में किसी बिंदु पर शून्य हो जाने पर एक कमजोर संदर्भ का उपयोग करें । इसके विपरीत, एक अज्ञात संदर्भ का उपयोग करें जब आप जानते हैं कि संदर्भ एक बार यह शून्य नहीं होगा क्योंकि इसे आरंभीकरण के दौरान सेट किया गया है। ”


0
import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let controller = storyboard.instantiateViewController(withIdentifier: "AnotherViewController")
        self.navigationController?.pushViewController(controller, animated: true)

    }

}



import UIKit
class AnotherViewController: UIViewController {

    var name : String!

    deinit {
        print("Deint AnotherViewController")
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        print(CFGetRetainCount(self))

        /*
            When you test please comment out or vice versa

         */

//        // Should not use unowned here. Because unowned is used where not deallocated. or gurranted object alive. If you immediate click back button app will crash here. Though there will no retain cycles
//        clouser(string: "") { [unowned self] (boolValue)  in
//            self.name = "some"
//        }
//


//
//        // There will be a retain cycle. because viewcontroller has a strong refference to this clouser and as well as clouser (self.name) has a strong refferennce to the viewcontroller. Deint AnotherViewController will not print
//        clouser(string: "") { (boolValue)  in
//            self.name = "some"
//        }
//
//


//        // no retain cycle here. because viewcontroller has a strong refference to this clouser. But clouser (self.name) has a weak refferennce to the viewcontroller. Deint AnotherViewController will  print. As we forcefully made viewcontroller weak so its now optional type. migh be nil. and we added a ? (self?)
//
//        clouser(string: "") { [weak self] (boolValue)  in
//            self?.name = "some"
//        }


        // no retain cycle here. because viewcontroller has a strong refference to this clouser. But clouser nos refference to the viewcontroller. Deint AnotherViewController will  print. As we forcefully made viewcontroller weak so its now optional type. migh be nil. and we added a ? (self?)

        clouser(string: "") {  (boolValue)  in
            print("some")
            print(CFGetRetainCount(self))

        }

    }


    func clouser(string: String, completion: @escaping (Bool) -> ()) {
        // some heavy task
        DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
            completion(true)
        }

    }

}

यदि आप इसके बारे में निश्चित नहीं हैं, [unowned self] तो उपयोग करें [weak self]

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.