这是我使用artworkImage
模糊一个名为UIImage+Effects
的UIImage来获取iOS 7模糊效果的方法:
-(void)viewDidAppear:(BOOL)animated{
MPMediaItem *currentItem = [self.musicPlayer nowPlayingItem];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul), ^(void) {
@autoreleasepool {
MPMediaItemArtwork *artwork = [currentItem valueForProperty: MPMediaItemPropertyArtwork];
UIImage *artworkImage = [artwork imageWithSize: CGSizeMake (618, 618)];
artworkImage = [artworkImage applyDarkEffect];
dispatch_async(dispatch_get_main_queue(), ^{
[backgroundImageView setImage:artworkImage];
UIGraphicsEndImageContext();
});
}
});
}
我的应用程序非常慢,所以我研究了如何找出原因,并且我遇到了仪器,它向我展示了这个:
所以我研究了一些如何解决这个问题,并遇到dispatch_async
,所以我将实际模糊放到后台并更新前面的UI。它仍然非常缓慢。
每次音乐播放器跳过歌曲时,此UIImage
都会更新artworkImage
。我将Apple的示例项目(称为UIImage+Effects.h
)中的iOS 7模糊效果应用于此UIImage。
请告诉我该做什么 - 我搜索了无数线程,这些线程都说使用autorelease
,我当然不能使用ARC。
非常感谢任何帮助,谢谢。
答案 0 :(得分:3)
这里最有可能发生的事情是你从上述处理中构建了一系列UIImages,导致你的应用程序最终耗尽内存并崩溃。
Apple的UIImage+Effects
类别使用一系列盒子模糊确实模糊了CPU端。它不是世界上最快的过程。除此之外,创建UIImage可能会很慢,就像将UIImage设置为UIImageView进行显示一样。几乎所有这些都是在CPU上完成的,而不是GPU。
因此,如果每次更新UI元素时触发上述方法,您将首先将一系列块调度到默认后台队列,然后异步调度到主队列。后者最有可能发生内存堆积,因为每个块都会保留其中的对象。如果您的处理和UIImageView更新花费的时间超过了触发上述方法的时间间隔,您将在调度队列中构建块,并且每个块都将在其中包含UIImages。这将很快导致内存堆积和崩溃。
有两种方法可以解决这个问题。首先,您可以使用调度信号量来确保每个后台队列上只运行一个块。我描述了一个用于此here的过程。这样可以防止内存累积,但可能无助于模糊速度。
为此,您可以查看Apple提供的模糊类别的替代方案。我的开源GPUImage框架具有GPU加速模糊replicates Apple's default effect。如果您需要更深层次的变体,我会谈谈如何修改此here的变体。往返于UIImages仍然很慢,但是通过将模糊传递到GPUImageView而不是UIImageView,你至少可以替换你在这里进行的慢速处理的后半部分。直接过滤到GPUImageView进行显示会将所有这些内容保留在GPU上。
答案 1 :(得分:0)