Я пытаюсь рисовать изображения на iPhone, используя закругленные углы, а также контактные изображения в приложении «Контакты». У меня есть код, который обычно работает, но он иногда вылетает внутри подпрограмм рисования UIImage с помощью EXEC_BAD_ACCESS
- KERN_INVALID_ADDRESS
. Я думал, что это может быть связано с cropping question Я спросил несколько недель назад, но я считаю, что правильно настраиваю путь отсечения.Округлые углы на UIImage
Вот код, который я использую - когда он не падает, результат выглядит отлично, и любой, кто хочет получить подобный вид, может свободно заимствовать код.
- (UIImage *)borderedImageWithRect: (CGRect)dstRect radius:(CGFloat)radius {
UIImage *maskedImage = nil;
radius = MIN(radius, .5 * MIN(CGRectGetWidth(dstRect), CGRectGetHeight(dstRect)));
CGRect interiorRect = CGRectInset(dstRect, radius, radius);
UIGraphicsBeginImageContext(dstRect.size);
CGContextRef maskedContextRef = UIGraphicsGetCurrentContext();
CGContextSaveGState(maskedContextRef);
CGMutablePathRef borderPath = CGPathCreateMutable();
CGPathAddArc(borderPath, NULL, CGRectGetMinX(interiorRect), CGRectGetMinY(interiorRect), radius, PNDegreeToRadian(180), PNDegreeToRadian(270), NO);
CGPathAddArc(borderPath, NULL, CGRectGetMaxX(interiorRect), CGRectGetMinY(interiorRect), radius, PNDegreeToRadian(270.0), PNDegreeToRadian(360.0), NO);
CGPathAddArc(borderPath, NULL, CGRectGetMaxX(interiorRect), CGRectGetMaxY(interiorRect), radius, PNDegreeToRadian(0.0), PNDegreeToRadian(90.0), NO);
CGPathAddArc(borderPath, NULL, CGRectGetMinX(interiorRect), CGRectGetMaxY(interiorRect), radius, PNDegreeToRadian(90.0), PNDegreeToRadian(180.0), NO);
CGContextBeginPath(maskedContextRef);
CGContextAddPath(maskedContextRef, borderPath);
CGContextClosePath(maskedContextRef);
CGContextClip(maskedContextRef);
[self drawInRect: dstRect];
maskedImage = UIGraphicsGetImageFromCurrentImageContext();
CGContextRestoreGState(maskedContextRef);
UIGraphicsEndImageContext();
return maskedImage;
}
и вот журнал аварий. Она выглядит так же, всякий раз, когда я получаю один из этих аварий
Exception Type: EXC_BAD_ACCESS (SIGSEGV) Exception Codes: KERN_INVALID_ADDRESS at 0x6e2e6181 Crashed Thread: 0 Thread 0 Crashed: 0 com.apple.CoreGraphics 0x30fe56d8 CGGStateGetRenderingIntent + 4 1 libRIP.A.dylib 0x33c4a7d8 ripc_RenderImage + 104 2 libRIP.A.dylib 0x33c51868 ripc_DrawImage + 3860 3 com.apple.CoreGraphics 0x30fecad4 CGContextDelegateDrawImage + 80 4 com.apple.CoreGraphics 0x30feca40 CGContextDrawImage + 368 5 UIKit 0x30a6a708 -[UIImage drawInRect:blendMode:alpha:] + 1460 6 UIKit 0x30a66904 -[UIImage drawInRect:] + 72 7 MyApp 0x0003f8a8 -[UIImage(PNAdditions) borderedImageWithRect:radius:] (UIImage+PNAdditions.m:187)
Почему ты CGContextSaveGState() и CGContextRestoreGState()? Читая документацию, создается впечатление, что состояние является внутренним для контекста, и весь контекст все равно отбрасывается. – 2009-07-02 13:53:18
Нужно ли вызывать CGContextBeginPath() и CGContextClosePath(), как вы это делаете? Я обнаружил, что могу просто создать путь и вызвать CGContextAddPath(), и все работает нормально. Кроме того, в документах для CGContextClosePath() говорится, что «когда вы заполняете или кликаете открытый путь, Quartz неявно закрывает для вас подпуть», предполагая, что его не нужно закрывать самостоятельно. – camdez 2009-10-23 23:04:42