2012-06-27 4 views
4

그래디언트와 광택 효과를 UButton에 추가하는 사용자 정의 UIButton 클래스가 있습니다. 코드는 iOS 4 및 iOS5 시뮬레이터에서 완벽하게 작동하지만 iOS 5 디바이스에서 실행할 때 나 예외 EXC_BAD_ACCESS는 예외가 선으로 트리거 : 어떤 도움이 정말 감사합니다CGContextStrokePath가 iOS에서 EXC_BAD_ACCESS를 트리거합니다. 5

CGContextStrokePath(context); 

, 여기 정말 싶어 지금은 그것이 정말 관련이 무엇인지 내 코드

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

    CGFloat actualBrightness = _brightness; 
    if (self.selected) { 
     actualBrightness -= 0.10; 
    } 

    CGColorRef blackColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:1.0].CGColor; 
    CGColorRef highlightStart = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.7].CGColor; 
    CGColorRef highlightStop = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.0].CGColor; 

    CGColorRef outerTop = [UIColor colorWithHue:_hue saturation:_saturation brightness:1.0*actualBrightness alpha:1.0].CGColor; 
    CGColorRef outerBottom = [UIColor colorWithHue:_hue saturation:_saturation brightness:0.80*actualBrightness alpha:1.0].CGColor; 

    CGFloat outerMargin = 7.5f; 
    CGRect outerRect = CGRectInset(self.bounds, outerMargin, outerMargin);    
    CGMutablePathRef outerPath = createRoundedRectForRect(outerRect, 6.0); 

    // Draw gradient for outer path 
    CGContextSaveGState(context); 
    CGContextAddPath(context, outerPath); 
    CGContextClip(context); 
    drawLinearGradient(context, outerRect, outerTop, outerBottom); 

    CGContextRestoreGState(context); 

    if (!self.selected) { 

     CGRect highlightRect = CGRectInset(outerRect, 1.0f, 1.0f); 
     CGMutablePathRef highlightPath = createRoundedRectForRect(highlightRect, 6.0); 

     CGContextSaveGState(context); 
     CGContextAddPath(context, outerPath); 
     CGContextAddPath(context, highlightPath); 
     CGContextEOClip(context); 

     drawLinearGradient(context, CGRectMake(outerRect.origin.x, outerRect.origin.y, outerRect.size.width, outerRect.size.height/3), highlightStart, highlightStop); 
     CGContextRestoreGState(context); 

     drawCurvedGloss(context, outerRect, 180); 
     CFRelease(highlightPath); 

    } 
    else { 
     //reverse non-curved gradient when pressed 
     CGContextSaveGState(context); 
     CGContextAddPath(context, outerPath); 
     CGContextClip(context); 
     drawLinearGloss(context, outerRect, TRUE);  
     CGContextRestoreGState(context); 

    } 
    if (!_toggled) { 
     //bottom highlight 
     CGRect highlightRect2 = CGRectInset(self.bounds, 6.5f, 6.5f); 
     CGMutablePathRef highlightPath2 = createRoundedRectForRect(highlightRect2, 6.0); 

     CGContextSaveGState(context); 
     CGContextSetLineWidth(context, 0.5); 
     CGContextAddPath(context, highlightPath2); 
     CGContextAddPath(context, outerPath); 
     CGContextEOClip(context); 
     drawLinearGradient(context, CGRectMake(self.bounds.origin.x, self.bounds.size.height-self.bounds.size.height/3, self.bounds.size.width, self.bounds.size.height/3), highlightStop, highlightStart); 

     CGContextRestoreGState(context); 
     CFRelease(highlightPath2); 
    } 
    else { 
     //toggle marker 
     CGRect toggleRect= CGRectInset(self.bounds, 5.0f, 5.0f); 
     CGMutablePathRef togglePath= createRoundedRectForRect(toggleRect, 8.0); 

     CGContextSaveGState(context); 
     CGContextSetLineWidth(context, 3.5); 
     CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor); 
     CGContextAddPath(context, togglePath); 
     CGContextStrokePath(context); 
     CGContextRestoreGState(context); 
     CFRelease(togglePath); 
    } 
    // Stroke outer path 
    CGContextSaveGState(context); 
    CGContextSetLineWidth(context, 0.5); 
    CGContextSetStrokeColorWithColor(context, blackColor); 
    CGContextAddPath(context, outerPath); 
    CGContextStrokePath(context); 
    CGContextRestoreGState(context); 

    CFRelease(outerPath); 

} 

입니다 iOS 5 또는 다른 문제가 있습니까?

+0

특히 사용자 정의 함수에 대한 액세스가없는 비교적 긴 디버깅 방법입니다. 몇 가지 중단 점을 설정하고이 방법의 어느 부분이 손상되었는지 알아 내려고 시도하십시오. 당신 중 한 명은 당신이 생각하는 그런 사람이 아닌 것 같아요. –

+1

잘 모르겠지만 SDK의 일부인 CGContextStrokePath (Context)에서 예외가 발생합니다.이 코드는 iOS 4와 iOS 5 시뮬레이터에서 완벽하게 작동합니다. 어떤 iOS 5 장치에서도 작동하지 않습니다. – ahmad

+0

또한 해당 코드에서 분기 (if-else-statements)를가집니다. 어떤 CGContextStrokePath()가 충돌하고 있습니까? –

답변

4

CGColorRefs에 액세스 할 때 UIColors가 이미 할당 해제 되었기 때문에 충돌이 발생합니다.

이를 방지하는 쉬운 방법은 너무 ARC는 UIColor 초기 오브젝트의 할당을 해제 할 수있는 기회를 얻을하지 않습니다

UIColor* blackColor = [UIColor blackColor]; 
CGContextSetStrokeColorWithColor(context, [blackColor CGColor]); 

대신

CGColorRef* blackColor = [[UIColor blackColor] CGColor]; 
CGContextSetStrokeColorWithColor(context, blackColor); 

으로 사용하는 것입니다.

+0

몇 주 동안 매우 까다로운 작업을하고 있었는데이 답변에 그것을 해결했다. 고맙습니다! – user1021430

관련 문제