खोज…


परिचय

यह विषय बताता है कि स्विफ्ट रनटाइम कब और कैसे डेटा डेटा संरचनाओं के लिए मेमोरी आवंटित करेगा, और जब उस मेमोरी को पुनः प्राप्त किया जाएगा। डिफ़ॉल्ट रूप से, मेमोरी बैकिंग क्लास इंस्टेंसेस को संदर्भ गिनती के माध्यम से प्रबंधित किया जाता है। संरचनाओं को हमेशा नकल के माध्यम से पारित किया जाता है। अंतर्निहित मेमोरी प्रबंधन योजना से बाहर निकलने के लिए, कोई [ Unmanaged ] [1] संरचना का उपयोग कर सकता है। [१]: https://developer.apple.com/reference/swift/unmanaged

टिप्पणियों

कमजोर कीवर्ड का उपयोग कब करें:

weak -कॉवर्ड का उपयोग किया जाना चाहिए, यदि संदर्भित वस्तु को संदर्भ रखने वाली वस्तु के जीवनकाल के दौरान निपटाया जा सकता है।

अन-कीवर्ड का उपयोग कब करें:

unowned -कीवर्ड का उपयोग किया जाना चाहिए, यदि संदर्भ को धारण करने वाली वस्तु के जीवनकाल के दौरान संदर्भित ऑब्जेक्ट से निपटने की उम्मीद नहीं की जाती है।

नुकसान

एक त्रुटि अक्सर वस्तुओं के संदर्भ बनाने के लिए भूल जाती है, जिन्हें किसी फ़ंक्शन के समाप्त होने के बाद, जैसे कि स्थान प्रबंधक, गति प्रबंधक, आदि पर रहना पड़ता है।

उदाहरण:

class A : CLLocationManagerDelegate
{
    init()
    {
        let locationManager = CLLocationManager()
        locationManager.delegate = self
        locationManager.startLocationUpdates()
    }
}

यह उदाहरण ठीक से काम नहीं करेगा, क्योंकि आरंभिक रिटर्न के बाद स्थान प्रबंधक से निपटा जाता है। उदाहरण चर के रूप में एक मजबूत संदर्भ बनाने के लिए उचित समाधान है:

class A : CLLocationManagerDelegate
{
    let locationManager:CLLocationManager

    init()
    {
        locationManager = CLLocationManager()
        locationManager.delegate = self
        locationManager.startLocationUpdates()
    }
}

संदर्भ चक्र और कमजोर संदर्भ

एक संदर्भ चक्र (या चक्र को बनाए रखना ) को इसलिए नाम दिया गया है क्योंकि यह ऑब्जेक्ट ग्राफ में एक चक्र को इंगित करता है:

चक्र बनाए रखें

प्रत्येक तीर एक वस्तु को दूसरे (एक मजबूत संदर्भ) को बनाए रखने का संकेत देता है। जब तक चक्र टूट नहीं जाता है, तब तक इन वस्तुओं के लिए मेमोरी को मुक्त नहीं किया जाएगा

एक चक्र बनाए रखा जाता है जब वर्गों के दो उदाहरण एक दूसरे को संदर्भित करते हैं:

class A { var b: B? = nil }
class B { var a: A? = nil }

let a = A()
let b = B()

a.b = b  // a retains b
b.a = a  // b retains a -- a reference cycle

दोनों उदाहरण वे कार्यक्रम समाप्त होने तक जीवित रहेंगे। यह एक अनुरक्षण चक्र है।

कमजोर संदर्भ

बनाए रखने के चक्र से बचने के लिए, चक्र को तोड़ने के लिए संदर्भ बनाते समय weak या unowned उपयोग करें।

class B { weak var a: A? = nil }

कमजोर या अज्ञात संदर्भ किसी उदाहरण की संदर्भ संख्या नहीं बढ़ाएगा। ये संदर्भ चक्र बनाए रखने में योगदान नहीं करते हैं। कमजोर संदर्भ nil हो जाता है जब वह वस्तु संदर्भित होती है।

a.b = b  // a retains b
b.a = a  // b holds a weak reference to a -- not a reference cycle

क्लोजर के साथ काम करते समय, आप कैप्चर सूचियों में weak और unowned उपयोग किए जा सकते हैं।

मैनुअल मेमोरी प्रबंधन

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

आप एक सी कार्य करने के लिए एक प्रकार-punned सूचक की आपूर्ति करने की जरूरत है, का उपयोग toOpaque की विधि Unmanaged एक कच्चे सूचक प्राप्त करने के लिए संरचना, और fromOpaque मूल उदाहरण ठीक करने के लिए:

setupDisplayLink() {
  let pointerToSelf: UnsafeRawPointer = Unmanaged.passUnretained(self).toOpaque()
  CVDisplayLinkSetOutputCallback(self.displayLink, self.redraw, pointerToSelf)
}

func redraw(pointerToSelf: UnsafeRawPointer, /* args omitted */) {
  let recoveredSelf = Unmanaged<Self>.fromOpaque(pointerToSelf).takeUnretainedValue()
  recoveredSelf.doRedraw()
}

ध्यान दें कि, का उपयोग करते हुए अगर passUnretained और समकक्षों, इसके साथ ही सभी सावधानी बरतने के लिए आवश्यक है unowned संदर्भ।

विरासत ऑब्जेक्ट-सी एपीआई के साथ बातचीत करने के लिए, कोई व्यक्ति किसी निश्चित ऑब्जेक्ट की संदर्भ संख्या को मैन्युअल रूप से प्रभावित करना चाह सकता है। इसके लिए Unmanaged पास संबंधित तरीके retain और release । फिर भी, यह passRetained और takeRetainedValue का उपयोग करने के लिए अधिक वांछित है, जो परिणाम को वापस करने से पहले बनाए रखते हैं:

func preferredFilenameExtension(for uti: String) -> String! {
  let result = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassFilenameExtension)
  guard result != nil else { return nil }

  return result!.takeRetainedValue() as String
}

इन समाधानों को हमेशा अंतिम उपाय होना चाहिए, और भाषा-मूल एपीआई हमेशा पसंद किए जाने चाहिए।



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow