2013-01-22 38 views
5

के तहत CAShapeLayer के साथ [UIBezierPath CGPath] का उपयोग करके क्रैश करें मुझे [UIBezierPath CGPath] का उपयोग करके CAShapeLayer एआरसी के तहत एक बीएडी एक्सेस त्रुटि मिल रही है। मैं विभिन्न तरीकों से पूरा करने की कोशिश की है, लेकिन मैं स्पष्ट नहीं कर रहा हूँ कि अगर समस्या है। मैं makeToPath विधि का परिणाम का उपयोग करने के दुर्घटना पृथक हैएआरसी

maskLayer = [CAShapeLayer layer]; 
maskLayer.path = [self makeToPath]; 

लेकिन इस दुर्घटना नहीं करता है:

maskLayer = [CAShapeLayer layer]; 
maskLayer.path = [self makeFromPath]; 

वहाँ makeToPath द्वारा बनाई पथ के साथ कुछ अवैध है? मैं एक बार मैं इस दुर्घटना को हल एक CABasicAnimation साथ रास्तों को और से इस्तेमाल की योजना बना रहा हूँ। सही एआरसी UIBezierPath से CGPathRef रों के लिए ब्रिजिंग क्या है?

-(CGPathRef)makeToPath 
{ 
    UIBezierPath* triangle = [UIBezierPath bezierPath]; 
    [triangle moveToPoint:CGPointZero]; 
    [triangle addLineToPoint:CGPointMake(self.view.frame.size.width,0)]; 
    [triangle addLineToPoint:CGPointMake(0, self.view.frame.size.height)]; 
    [triangle closePath]; 
    return [triangle CGPath]; 
} 

-(CGPathRef)makeFromPath 
{ 
    UIBezierPath*rect = [UIBezierPath bezierPathWithRect:self.view.frame]; 
    return [rect CGPath]; 
} 

अद्यतन तो मैं नीचे एक जवाब प्रति मेरी ज फ़ाइल बदल लेकिन मैं अभी भी दुर्घटना

-(CGPathRef)makeToPath CF_RETURNS_RETAINED; 
-(CGPathRef)makeFromPath CF_RETURNS_RETAINED; 

मैं भी बना रही है मेरी तरीकों जवाब here (प्रति एक UIBezierPath उदाहरण वापसी करने की कोशिश की हो रही है नीचे दिखाया गया है)। अभी भी कोई सफलता नहीं है। कोई भी मुझे इसे ठीक करने के तरीके पर लंबे समय तक स्पष्टीकरण देना चाहता है?

maskLayer.path = [[self makeToPath] CGPath];// CRASHES 
morph.toValue = CFBridgingRelease([[self makeToPath] CGPath]);// CRASHES 

-(UIBezierPath*)makeToPath 
{ 
    UIBezierPath* triangle = [UIBezierPath bezierPath]; 
    [triangle moveToPoint:CGPointZero]; 
    [triangle addLineToPoint:CGPointMake(self.view.frame.size.width,0)]; 
    [triangle addLineToPoint:CGPointMake(0, self.view.frame.size.height)]; 
    [triangle closePath]; 
    return triangle; 
} 
+0

के संभावित डुप्लिकेट [EXC \ _ARM \ _DA \ _ALIGN त्रुटि जब एक डिवाइस पर चल] (http: // stackoverflow.com/questions/14129785/exc-arm-da-align-error-when-running-on-a-device) –

+0

मैं का उपयोग करें कि अंतिम वाक्य रचना, होने '' makeToPath' लौट UIBezierPath * 'और उसके बाद का उपयोग कर' maskLayer। पथ = [[आत्म makeToPath] CGPath]; ', हर समय। लेकिन मैं तुरंत 'मास्कलेयर' का उपयोग कर रहा हूं, उदा। '[self.view.layer addSublayer: मास्कलेयर]'। अपना 'पथ' सेट करने के बाद आप 'मास्कलेयर' के साथ क्या कर रहे हैं? क्या आप हमें दिखा सकते हैं? – Rob

+1

@Rob - मैं कुछ कोड साफ, 'झपकी debugger' भाग गया और अब यह काम करता है। –

उत्तर

8

समस्या CGPath लौटने के साथ है। वापस लौटाया गया मान CGPathRef जो एआरसी द्वारा कवर नहीं किया जाता है। बाद विधि समाप्त होता है UIBezierPath आप बनाना जारी है। इस प्रकार CGPathRef को भी मुक्त कर रहा है।

ज फ़ाइल में: आप एआरसी आपका मंतव्य यह बताने के लिए एक स्रोत एनोटेशन निर्दिष्ट कर सकते हैं

-(CGPathRef)makeToPath CF_RETURNS_RETAINED; 
-(CGPathRef)makeFromPath CF_RETURNS_RETAINED; 
+0

धन्यवाद - मैं विधि 'bezierPathWithRect' समारोह का उपयोग कर के साथ दुर्घटना नहीं हो रही है। यह भ्रमित है। क्या आप जानते हैं कि वह दृष्टिकोण क्यों दुर्घटनाग्रस्त नहीं होता है? –

+1

हू। मुझे नहीं पता था कि उन एनोटेशन अभी तक उपयोग योग्य थे। यह कमाल है, धन्यवाद! (डॉक्स यहां उत्सुक हैं: http://clang.llvm.org/docs/AutomaticReferenceCounting.html#conversion-to-retainable-object-pointer-type-of-expressions-with-known-semantics) –

+0

@skinnyTOD : एक जारी वस्तु का उपयोग करने का व्यवहार अपरिभाषित है। – diederikh

3

के रूप में अन्य पोस्टर ने कहा, यदि आप एक CGPath संदर्भ एक UIBezierPath वस्तु से लिया लौट रहे हैं कि विधि के अंत में गुंजाइश से बाहर चला जाता है। UIBezierPath CGPath संपत्ति पर डॉक्स के रूप में कहते हैं:

पथ वस्तु ही UIBezierPath वस्तु के स्वामित्व और मान्य है केवल जब तक आप रास्ते पर आगे संशोधन करने के है।

आप अपने CGPath की एक प्रतिलिपि बनाने और आते हैं वो:

-(CGPathRef)makeToPath 
{ 
    UIBezierPath* triangle = [UIBezierPath bezierPath]; 
    [triangle moveToPoint:CGPointZero]; 
    [triangle addLineToPoint:CGPointMake(self.view.frame.size.width,0)]; 
    [triangle addLineToPoint:CGPointMake(0, self.view.frame.size.height)]; 
    [triangle closePath]; 
    CGPathRef theCGPath = [triangle CGPath]; 
    return CGPathCreateCopy(theCGPath); 
} 

तरह से मैं LLVM परियोजना के लिए लिंक पढ़ा है, मुझे लगता है कि cf_returns_retained क्वालीफायर फोन करने वाले को बताने के लिए करना है आपके लिए बनाए रखने के बजाय, लौटा मूल्य के लिए स्मृति प्रबंधन नीति।

इस प्रकार मैं आप दोनों पथ की एक प्रतिलिपि बनाने और cf_returns_retained क्वालीफायर से जोड़ना होगा लगता है। हालांकि, मैं उस क्वालीफायर के वाक्यविन्यास पर स्पष्ट नहीं हूं। (पहले कभी इसका इस्तेमाल नहीं किया।)

अन्य पोस्टर मानते हुए सही वाक्य रचना की थी, यह कुछ इस तरह दिखेगा:

-(CGPathRef)makeToPath CF_RETURNS_RETAINED; 
{ 
    UIBezierPath* triangle = [UIBezierPath bezierPath]; 
    [triangle moveToPoint:CGPointZero]; 
    [triangle addLineToPoint:CGPointMake(self.view.frame.size.width,0)]; 
    [triangle addLineToPoint:CGPointMake(0, self.view.frame.size.height)]; 
    [triangle closePath]; 
    CGPathRef theCGPath = [triangle CGPath]; 
    return CGPathCreateCopy(theCGPath); 
} 
+2

CF_RETURNS_RETAINED एनोटेशन वास्तव में केवल तभी जरूरी है जब आपकी विधि [कोरफाउंडेशन नामकरण नियम] (http://developer.apple.com/library/ios/DOCUMENTATION/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html के अनुरूप नहीं है # // apple_ref/doc/यूआईडी/20,001,148-103,029)। इसके बजाय आपके तरीकों का नाम बदलने की अनुशंसा की जाती है। –