Swift Language
स्मृति प्रबंधन
खोज…
परिचय
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
}
इन समाधानों को हमेशा अंतिम उपाय होना चाहिए, और भाषा-मूल एपीआई हमेशा पसंद किए जाने चाहिए।