5

UIButtonにグラデーションと光沢効果を追加するカスタムUIButtonクラスがありますが、コードはiOS 4とiOS5シミュレーターで完全に機能しますが、iOS 5デバイスで実行すると、例外EXC_BAD_ACCESSが発生し、例外はライン :

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に関連しているのか、それとも何か間違ったことをしているのかということです。

4

1 に答える 1

4

CGColorRefsにアクセスすると、UIColorsの割り当てがすでに解除されているため、クラッシュが発生します。

これを回避する簡単な方法は、

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

それ以外の

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

そのため、ARCはUIColorオブジェクトの割り当てを早期に解除する機会を得ることができません。

于 2012-12-28T13:10:30.700 に答える