面试题答案
一键面试性能优化策略
- 使用硬件加速:
- Core Graphics支持硬件加速,尽可能利用
CALayer
的特性。例如,将需要绘制的图形内容添加到CALayer
上,利用CALayer
的隐式动画和硬件加速能力。比如对于一些静态的阴影部分,可以直接设置CALayer
的shadowColor
、shadowOffset
、shadowRadius
和shadowOpacity
属性,系统会利用硬件加速来渲染阴影,而不需要我们手动绘制阴影,提高绘制效率。
- Core Graphics支持硬件加速,尽可能利用
- 减少不必要的绘制:
- 实现
drawRect:
方法时,通过CGRectIntersectsRect
等函数来判断当前需要绘制的区域与实际脏区域的交集,只绘制需要更新的部分。例如,如果只有一小部分区域发生了变化,就避免重新绘制整个视图。可以在视图类中定义一个属性记录脏区域,在每次绘制前更新这个脏区域,并在drawRect:
方法中根据脏区域进行绘制。 - 对于重复绘制的元素,可以缓存绘制结果。比如,如果有一些固定样式的图形需要反复绘制,可以将其绘制到一个
UIImage
或者CGImage
中,然后在需要绘制的地方直接绘制这个图像,而不是每次都重新绘制图形的细节。
- 实现
- 优化图像数据处理:
- 对于模糊等效果,如果使用
CIGaussianBlur
等滤镜,尽量在后台线程处理图像数据。例如,可以使用NSOperationQueue
创建一个后台队列,将图像数据处理任务添加到这个队列中。在处理完成后,将处理好的图像数据传递回主线程进行显示。这样可以避免阻塞主线程,保证应用的流畅性。 - 减少图像内存占用,在加载图像时,根据设备屏幕分辨率和实际需求对图像进行缩放。可以使用
UIImage
的imageWithData:scale:
方法来加载缩放后的图像,减少内存消耗,从而提高性能。
- 对于模糊等效果,如果使用
高级图形效果与Core Graphics结合实现
- 实时阴影:
- 手动绘制阴影可以使用
CGContextSetShadow
函数。首先获取当前的CGContextRef
,例如在drawRect:
方法中通过UIGraphicsGetCurrentContext()
获取。然后设置阴影的偏移量、模糊半径和颜色,如下代码示例:
- (void)drawRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetShadow(context, CGSizeMake(5, 5), 3); CGContextSetShadowColor(context, [UIColor blackColor].CGColor, 0.5); // 这里绘制需要添加阴影的图形,例如绘制一个矩形 CGContextAddRect(context, CGRectMake(100, 100, 200, 100)); CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor); CGContextFillPath(context); }
- 如果使用
CALayer
来实现阴影,如前面提到的,设置CALayer
的相关阴影属性即可。
- 手动绘制阴影可以使用
- 模糊效果:
- 使用Core Image框架结合Core Graphics实现模糊效果。首先创建一个
CIImage
对象,例如从一个UIImage
创建:
UIImage *originalImage = [UIImage imageNamed:@"exampleImage"]; CIImage *ciImage = [[CIImage alloc] initWithImage:originalImage];
- 然后使用
CIGaussianBlur
滤镜创建一个模糊的CIImage
:
CIFilter *blurFilter = [CIFilter filterWithName:@"CIGaussianBlur"]; [blurFilter setValue:ciImage forKey:kCIInputImageKey]; [blurFilter setValue:@(10) forKey:kCIInputRadiusKey]; CIImage *blurredCIImage = [blurFilter outputImage];
- 最后将模糊后的
CIImage
转换为UIImage
并绘制到视图上,例如在drawRect:
方法中:
- (void)drawRect:(CGRect)rect { CIContext *context = [CIContext contextWithOptions:nil]; CGImageRef cgImage = [context createCGImage:blurredCIImage fromRect:blurredCIImage.extent]; UIImage *blurredImage = [UIImage imageWithCGImage:cgImage]; CGImageRelease(cgImage); [blurredImage drawInRect:rect]; }
- 如前面优化策略提到的,将这部分图像数据处理放在后台线程,处理完成后再更新到主线程显示。
- 使用Core Image框架结合Core Graphics实现模糊效果。首先创建一个