एआरसी और ब्राइडेड कास्ट


166

एआरसी के साथ, मैं अब डाल सकता CGColorRefकरने के लिए id। मुझे पता चला कि मुझे एक कास्ट करने की जरूरत है। क्लैग डॉक्स के अनुसार :

एक पाटने डाली एक सी शैली डाली तीन किसी कीवर्ड के साथ टिप्पणी की जाती है:

(__bridge T) opगंतव्य प्रकार के लिए ऑपरेंड को निकालता है T। यदि T एक प्राप्य ऑब्जेक्ट पॉइंटर प्रकार है, तो opएक गैर-प्राप्य पॉइंटर प्रकार होना चाहिए। यदि Tएक गैर-पुन: प्रयोज्य सूचक प्रकार है, तो op में एक प्राप्य वस्तु सूचक प्रकार होना चाहिए। अन्यथा कलाकार बीमार है। स्वामित्व का कोई हस्तांतरण नहीं है, और एआरसी कोई भी संचालन नहीं करता है।

(__bridge_retained T) opगंतव्य को टाइप करने के लिए ऑपरेंड को कास्टेबल होना चाहिए, जिसके पास नॉन-रिटेंबल पॉइंटर टाइप होना चाहिए। एआरसी मूल्य को बरकरार रखता है, स्थानीय मूल्यों पर सामान्य अनुकूलन के अधीन है, और प्राप्तकर्ता उस +1 को संतुलित करने के लिए जिम्मेदार है।

(__bridge_transfer T) opगंतव्य को टाइप करने के लिए ऑपरेंड को कास्ट किया जाना चाहिए, जिसके पास नॉन-मेंटेबल पॉइंटर टाइप होना चाहिए, जो एक रिसेटेबल ऑब्जेक्ट पॉइंटर टाइप होना चाहिए। एआरसी स्थानीय मूल्यों पर सामान्य अनुकूलन के अधीन, पूर्ण अभिव्यक्ति के अंत में मूल्य जारी करेगा।

एआरसी नियंत्रण में और बाहर वस्तुओं को स्थानांतरित करने के लिए इन जातियों की आवश्यकता होती है; अनुरक्षण योग्य वस्तु बिंदुओं के रूपांतरण पर अनुभाग में औचित्य देखें।

एक का उपयोग करना __bridge_retainedया __bridge_transferएआरसी को समझाने के लिए फेंकना एक असंतुलित बनाए रखने या रिलीज के साथ किरदारों विशुद्ध रूप से क्रमश: खराब फार्म है।

मैं किस तरह की स्थितियों में प्रत्येक का उपयोग करूंगा?

उदाहरण के लिए, CAGradientLayerएक colorsसंपत्ति है जो CGColorRefएस की एक सरणी को स्वीकार करती है । मेरा अनुमान है कि मुझे __brigeयहाँ का उपयोग करना चाहिए , लेकिन वास्तव में मुझे क्यों (या नहीं करना चाहिए) स्पष्ट नहीं है।


17
क्या आपने अभी तक WWDC 2011 सत्र 323 देखा है? बताते हैं कि एआरसी मुझसे कहीं बेहतर है। इसमें शुरुआत से लेकर अंत तक सभी विवरण शामिल हैं। यह हर मैक / iOS डेवलपर के लिए एक सत्र देखना चाहिए।
rbrown

यह भी मदद कर सकता है: stackoverflow.com/questions/14352494/…
इवान मेलोर

WWDC सत्र के लिए लिंक, यह खोजने के लिए तुच्छ नहीं था: developer.apple.com/videos/play/wwdc2011/323 - प्रासंगिक बिट 23:15 पर है
डैनियल

जवाबों:


215

मैं सहमत हूं कि विवरण भ्रमित है। जब से मैंने उन्हें समझा, मैं संक्षेप में बताने की कोशिश करूंगा:

  • (__bridge_transfer <NSType>) opया वैकल्पिक CFBridgingRelease(op)रूप CFTypeRefसे एआरसी पर इसे स्थानांतरित करने के दौरान थोड़ी देर के रिटेन-काउंट का उपभोग करने के लिए उपयोग किया जाता है । यह भी प्रतिनिधित्व किया जा सकता हैid someObj = (__bridge <NSType>) op; CFRelease(op);

  • (__bridge_retained <CFType>) opया वैकल्पिक CFBridgingRetain(op)रूप से NSObjectइसे +1 रिटेन काउंट देते हुए CF-land को सौंपने के लिए उपयोग किया जाता है । आपको CFTypeRefइस तरह से बनाने के लिए संभालना चाहिए जैसे आप एक परिणाम को संभालेंगे CFStringCreateCopy()। यह भी प्रतिनिधित्व किया जा सकता हैCFRetain((__bridge CFType)op); CFTypeRef someTypeRef = (__bridge CFType)op;

  • __bridgeपॉइंटर-लैंड और ऑब्जेक्टिव-सी ऑब्जेक्ट-लैंड के बीच सिर्फ कास्ट होती है। यदि आपको उपरोक्त रूपांतरणों का उपयोग करने में कोई झुकाव नहीं है, तो इस का उपयोग करें।

शायद यह मददगार हो। खुद, मैं CFBridging…मैक्रो को सादे जातियों पर बहुत पसंद करता हूं ।


जब आप __bridge_transfer का उपयोग करते हैं तो क्या ऑब्जेक्ट्स की गिनती को आर्क द्वारा 1 से बढ़ा दिया जाता है? अन्यथा यह प्रतीत होता है कि पल CFRelease () कहा जाता है ऑब्जेक्ट चला गया है और कुछ भी नहीं करने के लिए इंगित करता है। इसी तरह, जब आप __bridge_retain का उपयोग करते हैं, तो क्या ARC op के रिटेन काउंट को 1 से कम कर देता है? और ऐसा लगता है कि वस्तु कभी भी ठीक से जारी नहीं होगी।
टोनी

2
एक बार एआरसी भूमि में आप केवल मजबूत और कमजोर संदर्भों के बारे में मायने नहीं रखते हैं।
11

4
हाँ, यदि आप केवल चाप भूमि में हैं तो मजबूत / कमज़ोर पर्याप्त होंगे, हालाँकि जब आप चाप और गैर-चाप वातावरण के बीच वस्तुओं का संक्रमण कर रहे होते हैं, तब भी आपको हुड के नीचे गणना के निहितार्थ के बारे में सोचना होगा
टोनी

3
ज़रुरी नहीं। आपको ARC भूमि के अंदर और बाहर जाने के बारे में सोचने की आवश्यकता है। और यह लोभी autoreleasing की काफी याद दिलाता है। (दिलचस्प रूप से पर्याप्त: एआरसी एक सामान्य पैटर्न को ठीक करता है जैसे किसी वस्तु को किसी शब्दकोश से बाहर निकालना और फिर उसका उपयोग करने से पहले उसे हटा देना, आदि)
मंकीडम

3
एनालाइज़र टूल (शिफ्ट + कमांड + बी) का उपयोग करने से इस तरह के संदेह को हल करने में मदद मिल सकती है, क्योंकि यह आपको एक प्राकृतिक भाषा में बताएगा कि क्या वर्तमान कोड मेमोरी लीक कर रहा है। यदि ऐसा होता है, तो आप संभवत: एक रिटेनिंग कास्ट का उपयोग कर रहे हैं, जबकि आपको एक गैर-रीटेनिंग कास्ट का उपयोग करना चाहिए। यदि एनालाइज़र आपको उस कोड लाइन्स में किसी भी चीज़ के बारे में चेतावनी नहीं देता है, तो आप शायद वर्तमान कोड
Fabio Napodano

55

मैंने iOS प्रलेखन में एक और स्पष्टीकरण पाया है जो मुझे लगता है कि समझना आसान है:

  • __bridge स्वामित्व के हस्तांतरण के साथ उद्देश्य-सी और कोर फाउंडेशन के बीच एक संकेतक स्थानांतरित करता है।

  • __bridge_retained (CFBridgingRetain)एक कोर फाउंडेशन पॉइंटर के लिए एक ऑब्जेक्टिव-सी पॉइंटर का उपयोग करता है और आप पर स्वामित्व स्थानांतरित करता है।

    आप ऑब्जेक्ट के स्वामित्व को त्यागने के लिए CFRelease या संबंधित फ़ंक्शन को कॉल करने के लिए जिम्मेदार हैं

  • __bridge_transfer (CFBridgingRelease)ऑब्जेक्टिव-सी के लिए एक नॉन-ऑब्जेक्टिव-सी पॉइंटर को स्थानांतरित करता है और एआरसी को स्वामित्व भी स्थानांतरित करता है।

    एआरसी वस्तु के स्वामित्व को त्यागने के लिए जिम्मेदार है

स्रोत: टोल-फ्री ब्रिजिड प्रकार


33

फॉलो-ऑन के रूप में, इस विशिष्ट मामले में, यदि आप iOS पर हैं, तो Apple UIColor और NSArray -CGColorमें CGColorRef को वापस करने के लिए इसकी विधि का उपयोग करने की सिफारिश करता है colorsएआरसी रिलीज नोट्स के लिए संक्रमण में , "द कम्पाइलर हैंडल सीएफ ऑब्जेक्ट्स कोकोआ के तरीकों से लौटे" के तहत, यह इंगित किया जाता है कि एक विधि का उपयोग करना-CGColor कोर फाउंडेशन ऑब्जेक्ट को रिटर्न स्वचालित रूप से संकलक द्वारा ठीक से संभाला जाएगा।

इस प्रकार, वे निम्नलिखित की तरह कोड का उपयोग करने का सुझाव देते हैं:

CAGradientLayer *gradientLayer = (CAGradientLayer *)[self layer];
gradientLayer.colors = [NSArray arrayWithObjects:(id)[[UIColor darkGrayColor] CGColor],
                                                 (id)[[UIColor lightGrayColor] CGColor], nil];

ध्यान दें कि अभी, Apple के उदाहरण कोड में (id) कास्ट याद आ रहा है, जो मेरे पास है, जो अभी भी संकलक त्रुटि से बचने के लिए आवश्यक है।


आप आमतौर पर वस्तुओं के पहले (आईडी) को उन सभी के बजाय (यदि आप पसंद करते हैं, तो) निकाल सकते हैं।
फिलिप सबौरिन

1
यह प्रश्न एआरसी के साथ कास्टिंग के बारे में पूछता है, जहां आपने जो कोड चिपकाया है वह कानूनी नहीं है।
जोए ह्रेडोर्न

11
@JoeyHagedorn - शायद आपने मेरे जवाब के पहले वाक्य में ARC प्रलेखन के लिए मेरा संदर्भ याद किया, लेकिन न केवल ARC के तहत यह मान्य है, यह इन UIColor कनवर्टर तरीकों से NSArrays में CGColorRef संदर्भ प्रदान करने के लिए अनुशंसित दृष्टिकोण है। मैं, और कई अन्य, एआरसी-सक्षम अनुप्रयोगों के भीतर इस सटीक कोड का उपयोग करते हैं। कोर फाउंडेशन ऑब्जेक्ट को वापस करने वाली विधि से तत्काल (आईडी) स्वचालित रूप से एआरसी को ऑब्जेक्ट को ठीक से पुल करता है।
ब्रैड लार्सन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.