经过数周的调试,我终于找到了表格视图滚动期间零星滞后的罪魁祸首。它们是-willChangeValueForKey:
并且-didChangeValueForKey:
需要外部二进制数据属性。
为方便起见,您可以将我的应用程序视为 Twitter 客户端。所以主要实体是Tweet
具有thumbnail_pic_data
我设置为的属性allowsExternalBinaryDataStorage
。一个相应的非持久属性被称为thumbnail_picture
被用作其方便的访问器。
表格视图是一个推文列表视图——时间线,每条推文都thumbnail_picture
显示在其相应单元格的内联中。图片是懒惰下载的。下载成功后,我thumbnail_pic_data
使用自定义设置器进行如下设置:
- (void)setThumbnail_pic_data:(NSData *)thumbnail_pic_data {
[self willChangeValueForKey:@"thumbnail_pic_data"]; // culprit
[self setPrimitiveThumbnail_pic_data:thumbnail_pic_data];
[self didChangeValueForKey:@"thumbnail_pic_data"]; // culprit
UIImage *picture;
if (thumbnail_pic_data) {
picture = [UIImage imageWithData:thumbnail_pic_data];
}
self.thumbnail_picture = picture;
}
使用上面的代码,我在每张图片下载后的表格视图滚动期间看到零星的滞后。在我发表评论willChangeValueForKey:
并didChangeValueForKey:
打电话后,滞后消失了。所以我知道他们是罪魁祸首。
但是,我用下面的代码得到的计时结果表明,它们长时间没有直接使用CPU:
CFAbsoluteTime t1 = CFAbsoluteTimeGetCurrent();
[self willChangeValueForKey:@"thumbnail_pic_data"];
CFAbsoluteTime t2 = CFAbsoluteTimeGetCurrent();
NSLog(@"willChangeValueForKey time: %f", t2 - t1);
[self setPrimitiveThumbnail_pic_data:thumbnail_pic_data];
CFAbsoluteTime t3 = CFAbsoluteTimeGetCurrent();
NSLog(@"setPrimitiveThumbnail_pic_data time: %f", t3 - t2);
[self didChangeValueForKey:@"thumbnail_pic_data"];
CFAbsoluteTime t4 = CFAbsoluteTimeGetCurrent();
NSLog(@"didChangeValueForKey time: %f", t4 - t3);
计时结果:
willChangeValueForKey 时间:0.000145
setPrimitiveThumbnail_pic_data 时间:0.001512
didChangeValueForKey 时间:0.001810willChangeValueForKey 时间:0.000138
setPrimitiveThumbnail_pic_data 时间:0.001418
didChangeValueForKey 时间:0.002211willChangeValueForKey 时间:0.000302
setPrimitiveThumbnail_pic_data 时间:0.001891
didChangeValueForKey 时间:0.003349willChangeValueForKey 时间:0.000162
setPrimitiveThumbnail_pic_data 时间:0.001462
didChangeValueForKey 时间:0.002114
作为临时解决方法,我将把这两个 KVO 调用注释掉。我不确定是否会发生任何不好的事情Core Data Programming Guide
说:
您必须确保调用相关的访问和更改通知方法(willAccessValueForKey:、didAccessValueForKey:、willChangeValueForKey:、didChangeValueForKey:、willChangeValueForKey:withSetMutation:usingObjects: 和 didChangeValueForKey:withSetMutation:usingObjects:)。
最重要的是,我想知道为什么这两个 KVO 调用会导致表格视图滚动缓慢,希望我能找到更好的解决方法。