Iphone 在GCD块中绘制图像时出现口吃

Iphone 在GCD块中绘制图像时出现口吃,iphone,ios,cocoa-touch,core-animation,grand-central-dispatch,Iphone,Ios,Cocoa Touch,Core Animation,Grand Central Dispatch,我有下面的方法,它将一些CAShapeLayers转换成UIImage。UIImage在单元格中用于UITableView(很像从库中选择照片时的照片应用程序)。从GCD块中调用此方法: -(UIImage*) imageAtIndex:(NSUInteger)index { Graphic *graphic = [[Graphic graphicWithType:index]retain]; CALayer *layer = [[CALayer alloc] init];

我有下面的方法,它将一些
CAShapeLayers
转换成
UIImage
UIImage
在单元格中用于
UITableView
(很像从库中选择照片时的照片应用程序)。从
GCD
块中调用此方法:

-(UIImage*) imageAtIndex:(NSUInteger)index
{
    Graphic *graphic = [[Graphic graphicWithType:index]retain];

    CALayer *layer = [[CALayer alloc] init];
    layer.bounds = CGRectMake(0,0, graphic.size.width, graphic.size.height);
    layer.shouldRasterize = YES;
    layer.anchorPoint = CGPointZero;
    layer.position = CGPointMake(0, 0);

    for (int i = 0; i < [graphic.shapeLayers count]; i++)
    {
        [layer addSublayer:[graphic.shapeLayers objectAtIndex:i]];
    }

    CGFloat largestDimension = MAX(graphic.size.width, graphic.size.height);
    CGFloat maxDimension = self.thumbnailDimension;
    CGFloat multiplicationFactor = maxDimension / largestDimension;
    CGSize graphicThumbnailSize = CGSizeMake(multiplicationFactor * graphic.size.width, multiplicationFactor * graphic.size.height);

    layer.sublayerTransform = CATransform3DScale(layer.sublayerTransform, graphicThumbnailSize.width / graphic.size.width, graphicThumbnailSize.height / graphic.size.height, 1);
    layer.bounds = CGRectMake(0,0, graphicThumbnailSize.width, graphicThumbnailSize.height);

    UIGraphicsBeginImageContextWithOptions(layer.bounds.size, NO, 0);
    [layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *image = [UIGraphicsGetImageFromCurrentImageContext() retain];
    UIGraphicsEndImageContext();

    [layer release];
    [graphic release];

    return [image autorelease];
}
-(UIImage*)imageAtIndex:(nsInteger)索引
{
Graphic*Graphic=[[Graphic graphicWithType:index]保留];
CALayer*layer=[[CALayer alloc]init];
layer.bounds=CGRectMake(0,0,graphic.size.width,graphic.size.height);
layer.shouldRasterize=是;
layer.anchorPoint=CGPointZero;
layer.position=CGPointMake(0,0);
对于(int i=0;i<[graphic.shapeLayers count];i++)
{
[图层添加子图层:[graphic.shapeLayers对象索引:i]];
}
CGFloat largestDimension=最大值(graphic.size.width,graphic.size.height);
CGFloat maxDimension=self.thumbnailDimension;
CGFloat乘法因子=最大维度/最大维度;
CGSize graphicsthumbnailsize=CGSizeMake(乘法因子*graphic.size.width,乘法因子*graphic.size.height);
layer.sublayerTransform=CATTransformM3DScale(layer.sublayerTransform,graphicThumbnailSize.width/graphic.size.width,graphicThumbnailSize.height/graphic.size.height,1);
layer.bounds=CGRectMake(0,0,graphicThumbnailSize.width,graphicThumbnailSize.height);
UIGraphicsBeginImageContextWithOptions(layer.bounds.size,NO,0);
[layer RenderContext:UIGraphicsGetCurrentContext()];
UIImage*image=[UIGraphicsGetImageFromCurrentImageContext()保留];
UIGraphicsSendImageContext();
[层释放];
[图片发布];
返回[图像自动释放];
}
无论出于何种原因,当我滚动
UITableView
并加载图像时,它有点口吃。我知道
GCD
代码很好,因为它以前工作过,所以代码中似乎有什么东西导致了口吃。有人知道那是什么吗?
CAAnimation
不是线程安全的吗?或者有谁知道一种更好的方法将一堆
cashapelayer
转换成
UIImage

最终我相信:

[layer renderInContext:UIGraphicsGetCurrentContext()];
无法在单独的线程上完成,因此我必须执行以下操作:

UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
//draw the mutable paths of the CAShapeLayers to the context
UIImage *image = [UIGraphicsGetImageFromCurrentImageContext() retain];
UIGraphicsEndImageContext(); 
在“在iOS上构建并发用户界面”的视频中有一个很好的例子(我在那里学会了这么做)

最后我相信:

[layer renderInContext:UIGraphicsGetCurrentContext()];
无法在单独的线程上完成,因此我必须执行以下操作:

UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
//draw the mutable paths of the CAShapeLayers to the context
UIImage *image = [UIGraphicsGetImageFromCurrentImageContext() retain];
UIGraphicsEndImageContext(); 

在“在iOS上构建并发用户界面”视频中有一个很好的例子(我在那里学会了这么做)

您是否使用仪器检查了帧率。另外,当您说您正在使用GCD时,您是在异步队列上运行整个过程。我相信你是的。另外,当你说“口吃”时,你能详细说明你所看到的是什么吗?是为即将进入视野的新细胞…@Srikanth-是的,图像加载到表中时的帧速率是35-40。然而,在我缓存它们之后,它是60。是的,它位于异步队列上。我所说的口吃是指当我以最快的速度滚动tableview时,滚动会变得不平稳,会有点走走停停(大概是为了加载)。你用仪器检查过帧率吗。另外,当您说您正在使用GCD时,您是在异步队列上运行整个过程。我相信你是的。另外,当你说“口吃”时,你能详细说明你所看到的是什么吗?是为即将进入视野的新细胞…@Srikanth-是的,图像加载到表中时的帧速率是35-40。然而,在我缓存它们之后,它是60。是的,它位于异步队列上。我所说的口吃是指当我以最快的速度滚动tableview时,滚动会变得不平稳,它会有点停下来然后走(大概是为了加载)。