我一直在努力追踪我们其中一个应用程序中的性能问题。似乎发生的情况是,有时 UIImageView 需要几秒钟来渲染图像,并且由于代码的编写方式,这会阻塞主线程。
我已经将问题归结为慢速图像是视网膜分辨率下的渐进 JPEG。无论出于何种原因,当文件达到一定大小时,解码 JPEG 就成为一项非常昂贵的操作。
无论如何,在编写一个简单的测试应用程序的过程中,我意识到我不知道如何计算绘制事件需要多长时间。它显然阻塞了主线程,所以我决定尝试计算运行循环迭代的时间。不幸的是,它最终有点骇人听闻。以下是相关代码:
///////////////
//
// This bit is used to time the runloop. I don't know a better way to do this
// but I assume there is... for now... HACK HACK HACK. :-)
buttonTriggeredDate_ = [NSDate date];
[[NSRunLoop mainRunLoop] performSelector:@selector(fire:) target:self argument:[NSNumber numberWithInt:0] order:1 modes:[NSArray arrayWithObject:NSDefaultRunLoopMode]];
///////////////
NSString* path = [[NSBundle mainBundle] pathForResource:imageName ofType:type];
self.imageView.image = [UIImage imageWithContentsOfFile:path];
回调如下(更多hackiness!):
- (void)fire:(NSNumber*)counter {
int iterCount = [counter intValue];
NSLog(@"mark %d", iterCount);
NSTimeInterval interv = [[NSDate date] timeIntervalSinceDate:buttonTriggeredDate_];
// We really need the second pass through - if it's less than X, assume
// it's just that first runloop iteration before the draw happens. Just wait
// for the next one.
if (iterCount < 1) {
iterCount++;
[[NSRunLoop mainRunLoop] performSelector:@selector(fire:)
target:self
argument:[NSNumber numberWithInt:iterCount]
order:1
modes:[NSArray arrayWithObject:NSDefaultRunLoopMode]];
} else {
self.statusDisplay.text = [NSString stringWithFormat:@"%@ - Took %f Seconds",
self.statusDisplay.text,
interv];
}
}
所以,我的问题是,基本上,你会怎么做?我希望能够放入不同的图像并运行基准测试,以确保我大致了解运行它需要多长时间。我也希望它合理一致且没有抖动。
嗯,也许我应该只继承 UIImageView 并记录时间[super drawRect:frame]
?
你会怎么做?