5

का उपयोग कर ढाल ड्राइंग करते समय CFArrayRef और NSArray के साथ समस्या मेरे पास एक एआरसी प्रोजेक्ट है और मैं एक लंबवत रैखिक ढाल खींचने की कोशिश कर रहा हूं। नीचे दिया गया कोड सिम्युलेटर पर काम करता है, लेकिन डिवाइस पर परीक्षण करते समय स्मृति/EXC_BAD_ACCESS त्रुटि फेंकता है। एप्लिकेशन कोड की निम्न दो पंक्तियों के साथ पर दुर्घटनाओं:एआरसी

NSArray *colorArray = [NSArray arrayWithObjects:(__bridge id)topColor, (__bridge id)bottomColor, nil]; 
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef) colorArray, colorLocations); 

कोड के उन दो लाइनों के लिए निम्न कोड से लिया जाता है (संदर्भ के लिए प्रदान की गई): किसी भी के लिए समय की

- (void)drawRect:(CGRect)rect 
{ 
    CGContextRef context = UIGraphicsGetCurrentContext(); 

    [self createGradientForContext:context andView:self.captionView]; 
    [self createGradientForContext:context andView:self.linksView]; 
    [self createGradientForContext:context andView:self.commentView]; 

} 

- (void)createGradientForContext:(CGContextRef)context andView:(UIView *)view 
{ 

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 

    CGFloat colorLocations[] = { 0.0f, 1.0f }; 

    CGColorRef topColor = [[UIColor colorWithRed:51.0f/255.0f green:51.0f/255.0f blue:51.0f/255.0f alpha:1.0f] CGColor]; 
    CGColorRef bottomColor = [[UIColor colorWithRed:48.0f/255.0f green:48.0f/255.0f blue:48.0f/255.0f alpha:1.0f] CGColor]; 
    NSArray *colorArray = [NSArray arrayWithObjects:(__bridge id)topColor, (__bridge id)bottomColor, nil]; 
    CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge_retained CFArrayRef) colorArray, colorLocations);  

    CGRect frame = view.frame; 
    CGPoint startPoint = CGPointMake(CGRectGetMidX(frame), CGRectGetMinY(frame)); 
    CGPoint endPoint = CGPointMake(CGRectGetMidX(frame), CGRectGetMaxY(frame)); 

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

    CGGradientRelease(gradient); 
    CGColorSpaceRelease(colorSpace); 

} 

धन्यवाद आगे और सभी मार्गदर्शन

+0

क्या आपको आर्क पसंद नहीं है? मेमोरी के प्रोग्रामर नियंत्रण को दूर लेना ... मैंने सोचा कि ऐप्पल ने कचरा संग्रह के साथ अपना सबक सीखा है। मैं इसका उपयोग नहीं करने की सिफारिश करता हूं ... –

+3

मैं एआरसी का उपयोग करने की सिफारिश करता हूं, वास्तव में एक अनिवार्य कारण होने की आवश्यकता नहीं है। – zaph

+0

आप ऑब्जेक्ट का उपयोग क्यों कर रहे हैं जब सब कुछ 'CFType' है? बस 'CFArray' का उपयोग करें और आपको ब्रिजिंग के बारे में चिंता करने की ज़रूरत नहीं है। –

उत्तर

5

केवल CFArrayRef का उपयोग करने का प्रयास करें और ब्रिजिंग से बचें और देखें कि इससे कोई फर्क पड़ता है या नहीं।

CGFloat topColorComps[] = {51.0f/255.0f, 51.0f/255.0f, 51.0f/255.0f, 1.0f}; 
CGFloat bottomColorComps[] = {48.0f/255.0f, 48.0f/255.0f, 48.0f/255.0f, 1.0f};    

CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB(); 
CGColorRef topColor = CGColorCreate(rgb, topColorComps); 
CGColorRef bottomColor = CGColorCreate(rgb, bottomColorComps); 
CGColorSpaceRelease(rgb); 

CFMutableArrayRef colorArray = CFArrayCreateMutable(NULL, 2, &kCFTypeArrayCallbacks); 
CFArrayAppendValue(colorArray, topColor); 
CFArrayAppendValue(colorArray, bottomColor); 

CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, colorArray, colorLocations); 

CFRelease(colorArray); 
CFRelease(topColor); 
CFRelease(bottomColor); 
+0

आपकी मदद के लिए धन्यवाद। अफसोस की बात है, यह मेरे डिवाइस पर चलते समय 'CFArrayAppendValue (colorArray, topcolor)' पर दुर्घटनाग्रस्त हो जाती है। – ArtSabintsev

+0

@ArtSabintsev: समस्या 'यूआईसीओलर' का उपयोग हो सकती है। मैंने ऊपर दिए गए उदाहरण को संपादित किया है, इस बार, आप सब कुछ के मालिक हैं। – dreamlax

+0

धन्यवाद! अब मुझे 'CGColorCreateGenericRGB अनुपलब्ध है' मिल रहा है। इसमें देख रहे हैं। – ArtSabintsev

7

अब समझाने के लिए आप क्यों दुर्घटनाग्रस्त थे ...

समस्या इन दो पंक्तियों है:

CGColorRef topColor = [[UIColor colorWithRed:51.0f/255.0f green:51.0f/255.0f blue:51.0f/255.0f alpha:1.0f] CGColor]; 
CGColorRef bottomColor = [[UIColor colorWithRed:48.0f/255.0f green:48.0f/255.0f blue:48.0f/255.0f alpha:1.0f] CGColor]; 

यह एक बहुत ही आम समस्या है; उन उपयोगकर्ताओं द्वारा स्टैक ओवरफ़्लो पर कई प्रश्न हैं जो इस से काट चुके हैं।

समस्या यह है कि उन यूआईसीओलर वस्तुओं को कभी भी उन पंक्तियों के बाद संदर्भित नहीं किया जाता है, इसलिए एआरसी उन्हें तुरंत रिलीज़ करता है- और क्योंकि उन यूआईसीओलर ऑब्जेक्ट्स सीजीकॉलर ऑब्जेक्ट्स का एकमात्र मालिक हैं, यूआईसीओलर्स तुरंत सीजीकॉलर्स को छोड़ देते हैं, जिससे आप दो मृतकों को छोड़ देते हैं CGColor वस्तुओं। जिसे आप फिर सरणी में डालने का प्रयास करते हैं।

जैसा कि आपने पाया, एनएसएआरएआरई से शुद्ध सीएफएआरएआरई में स्विच करने से यह ठीक नहीं होगा। यूआईसीओलर से शुद्ध CGColor तक स्विचिंग एक समाधान है; दूसरा CGColors पर अपना स्वामित्व रखना है:

CGColorRef topColor = CGColorRetain([[UIColor colorWithRed:51.0f/255.0f green:51.0f/255.0f blue:51.0f/255.0f alpha:1.0f] CGColor]); 
CGColorRef bottomColor = CGColorRetain([[UIColor colorWithRed:48.0f/255.0f green:48.0f/255.0f blue:48.0f/255.0f alpha:1.0f] CGColor]); 

⋮ 

CGColorRelease(topColor); 
CGColorRelease(bottomColor); 
+3

+1 होना चाहिए। मेरे लिए, यूआईसीओलर का उपयोग करने के लिए एक बेहतर समाधान है जब तक कि आप सरणी बनाते हैं: [एनएसएआरएआरए सरणीविथऑब्जेक्ट्स: (__ पुल आईडी) startColour.CGColor, (__bridge id) endColour.CGColor, nil]; – Cthutu

+0

@Cthutu: यह प्रभावी रूप से स्वयं को बनाए रखने के समान ही करता है-उस स्थिति में, सरणी उन्हें बरकरार रखती है। गैर-ढाल उद्देश्यों के लिए, 'myUIColor.CGColor' को सीधे 'CGContextSetFillColorWithColor' या इसी तरह से पास करने के लिए (जैसा कि इसे' CGColorRef' चर में छेड़छाड़ करने के बाद और फिर वहां से पुनर्प्राप्त करने के विपरीत) काम करना चाहिए, यदि वह कार्य या तो रंग ऑब्जेक्ट को बनाए रखता है या इसे रखने की कोशिश नहीं करता है। –

+0

हां यह वही बात है लेकिन आपको सभी CGColorRelease() कॉल की आवश्यकता नहीं है। रिलीज एआरसी में किया जाता है, न कि कोर फाउंडेशन कॉल। – Cthutu