Ios drawRect:/renderContext:问题

Ios drawRect:/renderContext:问题,ios,uiview,calayer,exc-bad-access,drawrect,Ios,Uiview,Calayer,Exc Bad Access,Drawrect,似乎在试图将我的观点纳入上下文时遇到了一些问题 我的基本设置是,我有一个视图控制器,它拥有一个UIPageViewController,我在其中加载控制器,其中的视图可以由用户的手指绘制。基本上我有一本书可以画进去 在书中翻页时,我通过调用 - (UIImage *)wholeImage { // Render the layer into an image and return UIGraphicsBeginImageContext(self.bounds.size);

似乎在试图将我的观点纳入上下文时遇到了一些问题

我的基本设置是,我有一个视图控制器,它拥有一个UIPageViewController,我在其中加载控制器,其中的视图可以由用户的手指绘制。基本上我有一本书可以画进去

在书中翻页时,我通过调用

- (UIImage *)wholeImage {
    // Render the layer into an image and return
    UIGraphicsBeginImageContext(self.bounds.size);
    [self.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *wholePageImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return wholePageImage;
}
然后将其返回值保存到文件中。然而,当我调用这个save方法时,就行了

[self.layer renderInContext:UIGraphicsGetCurrentContext()];
获取hit,它似乎调用了我的drawRect:method,该方法被覆盖如下

- (void)drawRect:(CGRect)rect {
    // Draw the current state of the image
    [self.currentImage drawAtPoint:CGPointMake(0.0f, 0.0f)];
    CGPoint midPoint1 = [self midPointOfPoint1:previousPoint1 point2:previousPoint2];
    CGPoint midPoint2 = [self midPointOfPoint1:currentPoint point2:previousPoint1];

    // Get the context
    CGContextRef context = UIGraphicsGetCurrentContext(); 

    // Add the new bit of line to the image
    [self.layer renderInContext:context];
    CGContextMoveToPoint(context, midPoint1.x, midPoint1.y);
    CGContextAddQuadCurveToPoint(context, previousPoint1.x, previousPoint1.y, midPoint2.x, midPoint2.y); 
    CGContextSetLineCap(context, kCGLineCapRound);
    CGContextSetLineWidth(context, self.lineWidth);
    if (self.drawMode == LNDrawViewDrawModeTipex) CGContextSetBlendMode(context, kCGBlendModeClear);
    else CGContextSetBlendMode(context, kCGBlendModeCopy);
    CGContextSetStrokeColorWithColor(context, self.lineColour.CGColor);
    CGContextStrokePath(context);

    // Call super
    [super drawRect:rect];
}
这是有道理的,但它似乎会被递归调用,直到我最终在这条线上获得EXC_BAD_访问权

[self.currentImage drawAtPoint:CGPointMake(0.0f, 0.0f)];
我完全不知道是什么导致了这一切,这让我发疯

如果有帮助的话,我的调用堆栈是这样开始的

然后递归进行,直到最后以

我真的很感激任何人都能给予的帮助和洞察力

编辑:已添加

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    // Get the touch
    UITouch *touch = [touches anyObject];

    // Get the points
    previousPoint2 = previousPoint1;
    previousPoint1 = [touch previousLocationInView:self];
    currentPoint = [touch locationInView:self];

    // Calculate mid point
    CGPoint mid1 = [self midPointOfPoint1:previousPoint1 point2:previousPoint2]; 
    CGPoint mid2 = [self midPointOfPoint1:currentPoint point2:previousPoint1];

    // Create a path for the last few points
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, NULL, mid1.x, mid1.y);
    CGPathAddQuadCurveToPoint(path, NULL, previousPoint1.x, previousPoint1.y, mid2.x, mid2.y);
    CGRect pathBounds = CGPathGetBoundingBox(path);
    CGPathRelease(path);

    // Take account of line width
    pathBounds.origin.x -= self.lineWidth * 2.0f;
    pathBounds.origin.y -= self.lineWidth * 2.0f;
    pathBounds.size.width += self.lineWidth * 4.0f;
    pathBounds.size.height += self.lineWidth * 4.0f;

    UIGraphicsBeginImageContext(pathBounds.size);
    [self.layer renderInContext:UIGraphicsGetCurrentContext()];
    self.currentImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    [self setNeedsDisplayInRect:pathBounds];    
}

您不能在drawRect:,句点中调用[self.layer renderInContext:]。如您所知,renderInContext:如果实现了drawRect:将调用它,这将导致无限递归

您应该单独渲染书本,然后使用渲染的图像让用户在其上绘制。一种方法是在UIGraphicsBeginImageContext/UIGraphicsSendImageContext块中包含一个自包含的图形代码,并在drawRect:中使用生成的图像。另一种方法是使用两个不同的视图,它们不是彼此的子视图,一个绘制未更改的书籍,另一个绘制用户草图

编辑:首先,你需要一个原始的图像书页面,随便什么。在UIGraphicsBeginImageContext/UIGraphicsSendImageContext块中绘制它,而不调用[self.layer renderContext:],并将其保存在视图的ivar中,例如self.currentImage。在TouchsMoved:withEvent:call setNeedsDisplay中,它将调用drawRect:以更新视图。使用drawRect:中的self.currentImage作为背景图像


希望我不是太含糊。

嗨,谢谢你的回复。大学教师;我不认为我完全明白你的意思。我刚刚在问题中添加了我的代码。我在UIGraphicsBeginImageContext/UIGraphicsSendImageContext块中绘制了一些代码,但除非我在drawRect中再次调用RenderContext,否则我似乎得到了一些相当大的市场行为….?drawRect似乎并不总是从RenderContext调用,因为我似乎能够在没有这个问题的情况下很好地绘制视图。。。!?我很困惑。我认为你的架构有点错误。基本上,你需要做两件不相关的事情:画一个图像和在上面画一些东西。由于它们是独立的,因此绘制最终结果的视图应该将原始/背景图像带到其他地方,而不是从其自身内容中。drawRect:的结果设置为视图的图层内容。renderInContext:每次可能调用drawRect:也可能不调用,这取决于您无法控制的许多因素。它可能使用缓存的映像,但这是一个实现细节。也可以将用户图形渲染到图像中,然后在drawRect:中绘制图像。当绘制到图像中时,可以使用上一次绘制的结果作为背景,累积绘制操作。drawRect:在这种情况下,我们总是绘制最终图像。很抱歉刚才看到了您的更新。问题是,如果不调用[self.layer renderInContext:],我无法获取原始图像,因为原始图像实际上就是已经绘制到层中的图像?