【发布时间】:2019-07-02 14:01:56
【问题描述】:
当界面由许多 CALayers 呈现时,我正在使用 IOS 应用程序。一旦我注意到 CPU 在图形更新期间被其他进程(实际上不是应用程序)加载。我开始禁用界面部件的更新,直到只有一个 CALayer 被更新(50-60 Hz),但所有其他层(数百个)都是静态的也显示出来了。因此,仅更新这一层会消耗 60-70% 的 CPU 其他进程的负载。当禁用此唯一层的更新时,CPU 不会加载。
谁能说说这是怎么回事?
[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
// update layer which is sublayer of self.view.layer
self.headingCircularScaleLayer.transform = CATransform3DMakeRotation(DegToRad(-newHeadingAngle_deg), 0, 0, 1);
[self.view.layer setNeedsLayout];
[CATransaction commit];
这里 headingCircularScaleLayer 是 CALayer,其内容设置为某个 Image
NOTE_1:(通过添加许多层并更新它们来测试 CPU 负载)
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
-(void) viewDidAppear:(BOOL)animated {
[self createAndSetupLayers];
CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateLayers)];
[displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
self.startTime = [[NSDate date] timeIntervalSince1970];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void) createAndSetupLayers {
NSMutableArray<CALayer*>* newLayersArray = [[NSMutableArray alloc] init];
long numOfRows = 28;
long numOfCols = 21;
long numOfLayers = numOfRows * numOfCols;
CGFloat cellWidth = self.view.bounds.size.width / numOfCols;
CGFloat cellHeight = self.view.bounds.size.height / numOfRows;
CGFloat layerWidth = cellWidth * 0.9;
CGFloat layerHeight = cellHeight * 0.9;
long currRow = 0;
long currCol = 0;
for (long i = 0; i < numOfLayers; i++)
{
currRow = i / numOfCols;
currCol = i % numOfCols;
CALayer* newLayer = [[CALayer alloc] init];
newLayer.bounds = CGRectMake(0.0, 0.0, layerWidth, layerHeight);
newLayer.anchorPoint = CGPointMake(0.5, 0.5);
newLayer.position = CGPointMake((currCol + 0.5) * cellWidth, (currRow + 0.5) * cellHeight);
newLayer.backgroundColor = [UIColor greenColor].CGColor;
//newLayer.opacity = 0.5;
//NSDictionary *newActions = @{ @"transform": [NSNull null] };
//newLayer.actions = newActions;
newLayer.actions = @{ @"contents": [NSNull null], @"position": [NSNull null],
@"frame": [NSNull null], @"opacity": [NSNull null],
@"bounds": [NSNull null], @"affineTransform": [NSNull null],
@"sublayerTransform": [NSNull null], @"transform": [NSNull null],
@"zPosition": [NSNull null], @"anchorPoint": [NSNull null],
@"cornerRadius": [NSNull null], @"sublayers": [NSNull null],
@"onLayout": [NSNull null], };
CALayer* newColorLayer = [[CALayer alloc] init];
newColorLayer.bounds = CGRectMake(0.0, 0.0, layerWidth, layerHeight);
newColorLayer.anchorPoint = CGPointMake(0.5, 0.5);
newColorLayer.position = CGPointMake(0.5 * layerWidth, 0.5 * layerHeight);
newColorLayer.opacity = 0.5;
newColorLayer.opaque = YES;
newColorLayer.backgroundColor = [UIColor redColor].CGColor;
//[newLayer addSublayer:newColorLayer];
[self.view.layer addSublayer:newLayer];
[newLayersArray addObject:newLayer];
}
self.layersArray = newLayersArray;
}
-(void) updateLayers {
double currTime = [[NSDate date] timeIntervalSince1970] - self.startTime;
double currLayerAngle = 0.5 * currTime;
NSLog(@"%.2f %.2f", currTime, currLayerAngle);
//[CATransaction begin];
//[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
//[CATransaction setAnimationDuration:0.0];
for (CALayer *currLayer in self.layersArray)
{
currLayer.transform = CATransform3DMakeRotation(currLayerAngle, 0, 0, 1);
}
//[CATransaction commit];
}
@end
【问题讨论】:
-
你能分享一些代码吗?您使用 CALayer 做什么以及如何做的?
-
你是在真机还是模拟器上测试?最好在真机上测试性能
-
添加代码到描述
-
我在真机上测试。在活动监视器中,它显示一些 backboardd 在更新期间占用了大量 CPU。
-
您必须将持续时间设置为 0.0s。所有动画属性都没有动画。否则默认时间为 0.25,这对性能问题不利。如果您只使用 disableActions,在这种情况下,
transform持续时间为 0.0,但其他,如不透明度、隐藏等,持续时间仍为 0.25 秒。换句话说,CATransaction 不应该立即完成。
标签: ios performance core-animation calayer cpu-usage