我一直在努力追踪我们的一个应用程序中的性能问题。似乎发生的情况是,有时 UIImageView 需要几秒钟来渲染图像,并且由于代码编写的方式,这会阻塞主线程。
我已经追查到这个问题是因为慢速图像是视网膜分辨率下的渐进式 JPEG。无论出于何种原因,当文件达到一定大小时,对 JPEG 进行解码成为一项非常昂贵的操作。
反正在写的过程中simple test application ,我意识到我不知道如何计算抽奖事件需要多长时间。它显然阻塞了主线程,所以我决定尝试对运行循环迭代进行计时。不幸的是,它最终有点骇人听闻。这是相关代码:
///////////////
//
// 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]
的时间?
你会怎么做?
最佳答案
您可能正在尝试为问题的错误部分计时。如您所料,问题很可能出在解码中(也可能出在内存分配和复制中)。问题不太可能出在最后的“绘图”步骤本身。
这就是 Instruments 专为解决的问题。启动 Instruments 并寻找您的热点。
作为一个可能的解决方案,如果 Instruments 告诉您解码是阻碍您的事情,您可以考虑在将图像放入 View 之前将图像渲染到后台线程上的 CALayer
上。
关于iphone - 如何测量 UIImageView 的绘制时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11104811/