मैं एआरसी में NSString
से प्राप्त करने के सही तरीके को समझने की कोशिश कर रहा हूं CFStringRef
? विपरीत दिशा जा रहा है, के लिए एक ही CFStringRef
करने के लिए NSString
एआरसी में?
मेमोरी लीक बनाए बिना ऐसा करने का सही तरीका क्या है?
मैं एआरसी में NSString
से प्राप्त करने के सही तरीके को समझने की कोशिश कर रहा हूं CFStringRef
? विपरीत दिशा जा रहा है, के लिए एक ही CFStringRef
करने के लिए NSString
एआरसी में?
मेमोरी लीक बनाए बिना ऐसा करने का सही तरीका क्या है?
retain
आईएनजी और release
वस्तुओं के संदर्भ संदर्भों का ध्यान रखने के बजाय , हमें अब "सुंदर" जैसे __bridge_transfer
, __unsafe_unretained
और का उपयोग करना चाहिए __autoreleasing
। किसी को भी इसके लिए समय नहीं मिला। (और गंभीरता से, यह पढ़ना मुश्किल है। मेरी राय में, यह स्मृति प्रबंधन की सुविधा नहीं देता है।)
जवाबों:
आम तौर पर
NSString *yourFriendlyNSString = (__bridge NSString *)yourFriendlyCFString;
तथा
CFStringRef yourFriendlyCFString = (__bridge CFStringRef)yourFriendlyNSString;
अब, यदि आप जानना चाहते हैं कि __bridge
खोजशब्द क्यों है, तो आप Apple प्रलेखन का उल्लेख कर सकते हैं । वहाँ आप पाएंगे:
__bridge
स्वामित्व के हस्तांतरण के साथ उद्देश्य-सी और कोर फाउंडेशन के बीच एक संकेतक स्थानांतरित करता है।
__bridge_retained
याCFBridgingRetain
एक कोर फाउंडेशन सूचक के लिए एक उद्देश्य-सी सूचक डाली और आप के लिए स्वामित्व स्थानांतरित करता है। आप ऑब्जेक्ट के स्वामित्व को त्यागने के लिए CFRelease या संबंधित फ़ंक्शन को कॉल करने के लिए जिम्मेदार हैं।
__bridge_transfer
याCFBridgingRelease
ऑब्जेक्टिव-सी के लिए नॉन-ऑब्जेक्टिव-सी पॉइंटर को मूव करता है और ओआरसी को ओनरशिप ट्रांसफर करता है। एआरसी वस्तु के स्वामित्व को त्यागने के लिए जिम्मेदार है।
जिसका अर्थ है कि उपरोक्त मामलों में आप स्वामित्व को बदले बिना ऑब्जेक्ट को कास्टिंग कर रहे हैं। इसका तात्पर्य यह है कि किसी भी स्थिति में आप स्ट्रिंग्स की मेमोरी को संभालने के प्रभारी नहीं होंगे।
ऐसा मामला भी हो सकता है जिसमें आप किसी कारण से स्वामित्व स्थानांतरित करना चाहते हैं।
उदाहरण के लिए निम्नलिखित स्निपेट पर विचार करें
- (void)sayHi {
CFStringRef str = CFStringCreateWithCString(NULL, "Hello World!", kCFStringEncodingMacRoman);
NSString * aNSString = (__bridge NSString *)str;
NSLog(@"%@", aNSString);
CFRelease(str); //you have to release the string because you created it with a 'Create' CF function
}
ऐसे मामले में आप CFRelease
कास्टिंग करते समय स्वामित्व को स्थानांतरित करके बचाना चाहते हैं ।
- (void)sayHi {
CFStringRef str = CFStringCreateWithCString(NULL, "Hello World!", kCFStringEncodingMacRoman);
NSString * aNSString = (__bridge_transfer NSString *)str;
// or alternatively
NSString * aNSString = (NSString *)CFBridgingRelease(str);
NSLog(@"%@", aNSString);
}
का स्वामित्व str
हस्तांतरित कर दिया गया है, इसलिए अब ARC आपके लिए मेमोरी जारी करेगा और रिलीज़ करेगा।
दूसरी तरह के आसपास आप एक डाल सकता पर NSString *
एक करने के लिए CFString
एक का उपयोग कर __bridge_retained
कि आप वस्तु के स्वामी होंगे और आप स्पष्ट रूप से का उपयोग करके इसे जारी करने के लिए होगा, डाली तो CFRelease
।
इसे लपेटने के लिए आपके पास हो सकता है
// Don't transfer ownership. You won't have to call `CFRelease`
CFStringRef str = (__bridge CFStringRef)string;
// Transfer ownership (i.e. get ARC out of the way). The object is now yours and you must call `CFRelease` when you're done with it
CFStringRef str = (__bridge_retained CFStringRef)string // you will have to call `CFRelease`
// Don't transfer ownership. ARC stays out of the way, and you must call `CFRelease` on `str` if appropriate (depending on how the `CFString` was created)
NSString *string = (__bridge NSString *)str;
// Transfer ownership to ARC. ARC kicks in and it's now in charge of releasing the string object. You won't have to explicitly call `CFRelease` on `str`
NSString *string = (__bridge_transfer NSString *)str;
NSString->CFString
, हमें उपयोग करना चाहिए __bridge
। लेकिन जब CFString->NSString
, हमें उपयोग करना चाहिए__bride_transfer
। ? और कोई भी साइड-इफ़ेक्ट, अगर हम CFRelease
तब उपयोग करते हैं जब हमें ज़रूरत नहीं होती है। धन्यवाद :)
CFRelease
आपके कार्यक्रम को यथोचित रूप से क्रैश कर सकता है, क्योंकि आप बेमेल बनाए रखने / रिलीज़ ऑपरेशन के साथ समाप्त हो जाएंगे, अंततः एक NULL
पॉइंटर जारी करेंगे ।
CFStringRef foo (__bridge CFStringRef)theNSString;
औरNSString *bar = (__bridge NSString *)theCFString;