2011-11-16 12 views
7

पर मेरे पास एक कोड है जो बिना किसी समस्या के संकलित करता है। यह आईफोन सिम्युलेटर पर अच्छा प्रदर्शन करता है, लेकिन मेरे डिवाइस पर, मुझे एक EXC_BAD_ACCESS मिलता है।सीजी ग्रेडियंट सिम्युलेटर पर चलता है, लेकिन आईफोन

यह ढाल बनाने के लिए एक सहायक कार्य में होता है। मैंने ऐसा करने के लिए this tutorial का पालन किया। इस प्रकार कोड रहा है:।

- (void) drawRect:(CGRect)rect 
{ 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGColorRef whiteColor = [UIColor whiteColor].CGColor; 
    CGColorRef lightGrayColor = [UIColor colorWithRed:230.0/255.0 
               green:230.0/255.0 
               blue:230.0/255.0 
               alpha:1.0].CGColor; 
    CGColorRef separatorColor = [UIColor colorWithRed:208.0/255.0 
               green:208.0/255.0 
               blue:208.0/255.0 
               alpha:1.0].CGColor; 
    CGRect paperRect = self.bounds; 
    CGRect nameRect = self.nameLabel.frame; 
    CGPoint sepStartPoint = CGPointMake(nameRect.origin.x, 
             nameRect.origin.x + nameRect.size.height + 2); 
    CGPoint sepEndPoint = CGPointMake(nameRect.origin.x + nameRect.size.width, 
             nameRect.origin.x + nameRect.size.height + 2); 

    drawLinearGradient(context, paperRect, lightGrayColor, whiteColor); 
    draw1PxStroke(context, sepStartPoint, sepEndPoint, separatorColor); 

} 


// Callee, where the problem is 
void drawLinearGradient(CGContextRef context, 
         CGRect rect, 
         CGColorRef startColor, 
         CGColorRef endColor) 
{ 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
    CGFloat locations[] = { 0.0, 1.0 }; 

    NSArray *colors = [NSArray arrayWithObjects: 
         (__bridge id)startColor, 
         (__bridge id)endColor, 
         nil]; // Here is the line 

    CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, 
                 (__bridge CFArrayRef) colors, locations); 

    CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect)); 
    CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect)); 

    CGContextSaveGState(context); 
    CGContextAddRect(context, rect); 
    CGContextClip(context); 
    CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0); 
    CGContextRestoreGState(context); 

    CGGradientRelease(gradient); 
    CGColorSpaceRelease(colorSpace); 
} 

Xcode पर प्रकाश डाला 12 (nil]; त्रुटि पंक्ति के रूप में के साथ एक लाइन

पीटर Hosey के लिए, यहाँ डिबगर उत्पादन है:

(gdb) po startColor 
<CGColor 0x1deca0> [<CGColorSpace 0x1d3280> (kCGColorSpaceDeviceGray)] (1 1) 
Current language: auto; currently objective-c 
(gdb) po endColor 
<CGColorSpace 0x1bf120> (kCGColorSpaceDeviceRGB) 
(gbd) 

मेरे सिम्युलेटर (और आईफोन) आईओएस 5 पर चलता है।

इस दुर्घटना का कारण क्या हो सकता है?

+0

संभवत: प्रारंभ में से एक का चयन करें या अंत रंग एक खतरनाक सूचक है; क्या आप ड्रॉलाइनरग्राइडेंट को कॉल करने वाले कोड को दिखा सकते हैं? – Tommy

+0

मैंने कॉलिंग कोड – ksol

+0

के साथ गिस्ट को अपडेट किया है यदि आप डीबगर कंसोल में 'po startcolor 'और' po endcolor' टाइप करते हैं, तो आपको क्या मिलता है? –

उत्तर

14

इसके आसपास काम करने का एक तरीका CGColorRefs की बजाय यूआईसीओलर्स को आपके फ़ंक्शन में पास करना होगा, और colors सरणी के प्रत्येक तत्व के लिए (id)[color1 CGColor] कास्ट का उपयोग करना होगा। यह सबसे लोकप्रिय तरीका प्रतीत होता है कि लोग अभी इस समस्या को संबोधित कर रहे हैं।

मैं this answer में इसका एक उपयोग इंगित करता हूं, और इस बारे में this Apple developer forum thread में इसके बारे में विस्तृत चर्चा हुई है। यदि आप अपने एनएसएआरएआरए को घोषित करने के बिंदु पर यूआईसीओलर की -CGColor विधि का उपयोग करते हैं, और आईडी पर डाले जाते हैं, तो सबकुछ आपके लिए स्वचालित रूप से ब्रिज हो जाता है।

स्वत: मामले प्रलेखन द्वारा वर्णित एक ऑब्जेक्टिव-सी विधि है कि एक CF प्रकार देता है और उसके बाद तुरंत एक Objective- लिए परिणाम कास्टिंग बुला के लिए एक ही लागू होता है: ऊपर से जुड़े मंच धागा में gparker राज्यों के रूप में सी वस्तु प्रकार। यदि आप विधि परिणाम के साथ कुछ और करते हैं, जैसे इसे सीएफ प्रकार के चर के रूप में असाइन करें, तो यह अब स्वचालित नहीं है।

hatfinch बताते हैं, यह अर्थ हो सकता है कि आपके CGColorRefs अस्थायी चर में रखा पिछली बार जब आप अपने UIColors संदर्भ के बाद चारों ओर लटका नहीं होगा, जब तक आप उन्हें स्पष्ट रूप से बरकरार रहती है। उस मंच धागे में दूसरों की तरह, मैंने गलती से सोचा कि यह ब्रिजिंग कार्यान्वयन में एक बग था, लेकिन मैं देख सकता हूं कि मैं यह गलत पढ़ रहा था।

+2

क्या वास्तव में यह एक एआरसी बग है, यद्यपि? [एआरसी spec] (http://clang.llvm.org/docs/AutomaticReferenceCounting.html) कहता है कि सीएफ ऑब्जेक्ट संदर्भों को "बनाए रखने योग्य ऑब्जेक्ट पॉइंटर्स" नहीं माना जाता है, जिसका अर्थ है कि एआरसी का मतलब CGColors को बनाए रखने के लिए नहीं है। सीजीकॉलर्स से निकाले जाने के बाद यूआईसीओलर्स का संदर्भ नहीं दिया जाता है, इसलिए उनके लिए लंबे समय तक रहने की उम्मीद करने के लिए कोई भरोसेमंद कारण नहीं है। यदि यूआईसीओलर्स सीजीकॉलर्स के मालिक हैं, तो वे सीजीकोलर्स को उनके साथ ले जाने पर ले जाएंगे। –

+1

आपका कामकाज काम करेगा, लेकिन इसलिए नहीं क्योंकि एआरसी में एक बग है; यह इरादे से व्यवहार कर रहा है (पीटर की टिप्पणी और मेरा जवाब देखें)। – hatfinch

+0

@ पीटर होसे - आह, काफी बग नहीं है, क्योंकि मैंने लिंक किए गए फोरम थ्रेड के शीर्ष के पास यह याद किया: "दस्तावेज़ीकरण द्वारा वर्णित स्वचालित केस केवल एक उद्देश्य-सी विधि को कॉल करने के लिए लागू होता है जो एक सीएफ प्रकार देता है और फिर तुरंत कास्टिंग करता है परिणाम ऑब्जेक्टिव-सी ऑब्जेक्ट प्रकार का परिणाम। यदि आप विधि परिणाम के साथ कुछ और करते हैं, जैसे कि इसे एक सीएफ प्रकार के चर के लिए असाइन करें, तो यह अब स्वचालित नहीं है। " एनएसएआरएआरई काम के भीतर प्रत्यक्ष उपयोग की वजह से यह एक बग की तरह लग रहा था, लेकिन अस्थायी CGColorRef असाइनमेंट नहीं। '-CGColor' विधि एक विशेष मामला प्रतीत होता है। –

12

आप अपने श्वेत रंग और lightGrayColor जीवित नहीं रख रहे हैं। आप CGColorRefs प्राप्त करते हैं जिनके पास आपके पास UIColors से स्वामित्व नहीं है जिन्हें कभी नहीं रखा जाता है। आपका कोड पढ़ना चाहिए:

CGColorRef whiteColor = CFRetain([UIColor whiteColor].CGColor); 
CGColorRef lightGrayColor = CFRetain([UIColor colorWithRed:230.0/255.0 green:230.0/255.0 blue:230.0/255.0 alpha:1.0].CGColor); 
CGColorRef separatorColor = CFRetain([UIColor colorWithRed:208.0/255.0 green:208.0/255.0 blue:208.0/255.0 alpha:1.0].CGColor); 

// ... 

drawLinearGradient(context, paperRect, lightGrayColor, whiteColor); 
draw1PxStroke(context, sepStartPoint, sepEndPoint, separatorColor); 

CFRelease(whiteColor); 
CFRelease(lightGrayColor); 
CFRelease(separatorColor); 

आप एप्पल याचिका सकता घोषित करने के लिए - [UIColor CGColor] objc_returns_inner_pointer, जो आपके कोड को आसान बनाने होगा, लेकिन उस विशेषता वास्तव में गैर retainable संकेत के लिए आरक्षित है के रूप में।

+0

यह गलत धारणा I (और अन्य) की तुलना में बहुत अधिक समझ में आता है कि यह एक एआरसी बग था। ऐसा लगता है कि '-CGColor' विधि से बाहर निकलने पर एनएसओब्जेक्ट को सीधी कास्टिंग एक विशेष मामला है, और इससे मुझे कुछ भ्रम पैदा हुआ। –

संबंधित मुद्दे