टी वह पुल कीवर्ड can be found here के उपयोग पर दस्तावेज़ीकरण। विशेष रूप से, मैं §3.2.4 कहना चाहता हूँ:
(__bridge T) op
गंतव्य प्रकार टी संकार्य डाले टी एक retainable वस्तु सूचक प्रकार है, तो सेशन एक गैर retainable सूचक प्रकार होना चाहिए। यदि टी एक गैर-रखरखाव सूचक प्रकार है, तो ऑप में एक टिकाऊ ऑब्जेक्ट पॉइंटर प्रकार होना चाहिए। अन्यथा कास्ट खराब गठित है। स्वामित्व का कोई हस्तांतरण नहीं है, और एआरसी सम्मिलित संचालन को बरकरार रखता है।
(__bridge_retained T) op
ऑपरेंड को रोकता है, जिसमें गंतव्य प्रकार के लिए बनाए रखने योग्य ऑब्जेक्ट पॉइंटर प्रकार होना चाहिए, जो एक गैर-रखरखाव सूचक प्रकार होना चाहिए। एआरसी मूल्य को बरकरार रखता है, स्थानीय मूल्यों पर सामान्य अनुकूलन के अधीन, और प्राप्तकर्ता उस +1 को संतुलित करने के लिए ज़िम्मेदार है।
(__bridge_transfer T) op
संकार्य, जो, गैर retainable सूचक प्रकार होना आवश्यक है गंतव्य प्रकार है, जो एक retainable वस्तु सूचक प्रकार होना चाहिए करने के लिए डाले। एआरसी स्थानीय मूल्यों पर सामान्य अनुकूलन के अधीन, संलग्न पूर्ण अभिव्यक्ति के अंत में मूल्य जारी करेगा। जबकि अपने NSMutableArray एक retainable सूचक प्रकार है
सूचक आप (void*
) में पारित किया जा रहा हो, एक गैर retainable सूचक प्रकार है। यह __bridge_retained
सीधे बाहर नियम। तो सवाल है, __bridge
या __bridge_transfer
पर?
__bridge_transfer
आम तौर पर प्रयोग किया जाता है जब आप एक विधि है कि एक CF वस्तु है कि बनाए रखा गया है रिटर्न से ऑब्जेक्टिव-सी सूचक चाहते हैं। उदाहरण के लिए, CFStringCreateWithFormat एक बनाए गए CFString को वापस कर देगा, लेकिन यदि आप इससे एनएसएसटींग चाहते हैं, तो आपको उनके बीच __bridge_transfer
की आवश्यकता होगी। इससे एआरसी उस ऑब्जेक्ट को रिलीज कर देगा जो सीएफ को उपयुक्त होने पर बनाए रखा जाएगा। उदाहरण के लिए, NSString* str = (__bridge_transfer NSString*) CFStringCreateWithFormat(...);
आपका कोड ऐसा नहीं कर रहा है, आपको स्वामित्व के साथ दखल देने की आवश्यकता नहीं है।आपकी मुख्य विधि इसके मेमोरी प्रबंधन के नियंत्रण में है, और यह केवल उस विधि के संदर्भ में गुज़र रही है जो इसे कॉल करती है (यद्यपि अप्रत्यक्ष रूप से, लेकिन यह सब मुख्य के दायरे में है)। इस प्रकार, आप __bridge
का उपयोग करेंगे।
लेकिन प्रतीक्षा करें, जब मैं __bridge का उपयोग करता हूं, तो मेरे कोड को स्मृति पहुंच त्रुटियां मिलती हैं !?
आह, यह आपके द्वारा पोस्ट किए गए कोड के साथ एक मुद्दा है, और पूरे ब्रिजिंग चर्चा के संबंध में नहीं है। आपके प्रसंस्करण फ़ंक्शन _processPathElement
के लिए आपको void*
CGApplyPath पर पास करने की आवश्यकता है। आप जो पास कर रहे हैं वह NSMutableArray**
है।
जब आप NSMutableArray*
पर पुन: प्रयास करते हैं, तो आप वास्तव में NSMutableArray**
कास्टिंग कर रहे हैं। यह कुख्यात EXC_BAD_ACCESS का कारण बन जाएगा। आपको पॉइंटर को पास करने की ज़रूरत है, पॉइंटर को पॉइंटर नहीं। लेकिन, CGPathApply(path, pathPoints, _processPathElement)
काम नहीं करेगा, आप NSMutableArray*
को void*
के रूप में पास नहीं कर सकते हैं। आपको क्या चाहिए (विडंबनात्मक रूप से), एक पुल है। पहले के समान कारणों से, आपको केवल __bridge
की आवश्यकता है। कोड नीचे देखें, जगह में सही पुलों के साथ, और उम्मीद के रूप में काम:
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
void _processPathElement(void* info, const CGPathElement* element)
{
NSMutableArray *array = (__bridge NSMutableArray*) info;
switch (element->type)
{
case kCGPathElementMoveToPoint:
case kCGPathElementAddLineToPoint:
{
CGPoint point = element->points[0];
[array addObject:[NSValue valueWithCGPoint:point]];
break;
}
default:
break;
}
}
int main(int argc, char *argv[])
{
@autoreleasepool
{
//Create path
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint( path, NULL, 0, 0);
CGPathAddLineToPoint(path, NULL, 1, 0);
CGPathAddLineToPoint(path, NULL, 1, 1);
CGPathAddLineToPoint(path, NULL, 0, 1);
CGPathCloseSubpath(path);
NSMutableArray *pathPoints = [[NSMutableArray alloc] init];
CGPathApply(path, (__bridge void*)pathPoints, _processPathElement);
NSLog(@"Points:%@", pathPoints);
}
}
यह प्रिंट आउट देगा:
Points:(
"NSPoint: {0, 0}",
"NSPoint: {1, 0}",
"NSPoint: {1, 1}",
"NSPoint: {0, 1}"
)
मुझे समझ नहीं आता। एक्सकोड द्वारा सुझाए गए अनुसार मैंने बस '__bridge' का उपयोग किया। और आपका प्रोग्राम संकलित करता है। – esh
या आप इसे ढूंढ रहे हैं, '__bridge' स्वामित्व के हस्तांतरण के बिना उद्देश्य-सी और कोर फाउंडेशन के बीच एक सूचक स्थानांतरित करता है। '__bridge_retained' या 'CFBridgingRetain' कोर फाउंडेशन पॉइंटर को ऑब्जेक्टिव-सी पॉइंटर बनाता है और आपको स्वामित्व स्थानांतरित करता है। आप ऑब्जेक्ट के स्वामित्व को छोड़ने के लिए CFRelease या संबंधित फ़ंक्शन को कॉल करने के लिए ज़िम्मेदार हैं। '__bridge_transfer' या 'CFBridgingRelease' उद्देश्य-सी के लिए एक गैर-उद्देश्य-सी सूचक को स्थानांतरित करता है और एआरसी को स्वामित्व स्थानांतरित करता है। एआरसी वस्तु के स्वामित्व को छोड़ने के लिए जिम्मेदार है। – esh
@ ब्लैकफैम 3 (पहली टिप्पणी) यह संकलन करने के लिए कोड प्राप्त करने का एक मामला नहीं है। मुझे स्मृति को सही ढंग से बनाए रखने की आवश्यकता है ताकि मेरे पास 'NSLog' –