当在任何imageWithSize:
对象上调用MPMediaItemArtwork
时,即使已经删除了对关联的MPMediaItem
和UIImage
的所有引用,内存仍然保持不变有一个神奇的参考抓住它。
我已经创建了一个完整的单独项目来测试这个特定的泄漏,我非常担心这是内部API的一个问题,而且我无能为力。
现在让我们进入一些好的事情。码。一个视图控制器和3个简单步骤将重现此问题。我的代码如下:
MPMediaItemCollection
个对象的数组(每个集合中只有一首歌,用于最坏情况的场景测试)MPMediaItem
中的每个代表MPMediaItemCollection
,都会生成一张专辑图片,其中CGSize
为500x500。NSTimer
,只会将与图像关联的所有数组设置为nil
ViewController.m:
#import <MediaPlayer/MediaPlayer.h>
#import "ViewController.h"
@interface ViewController ()
@property NSMutableArray *representativeImageArray;
@property NSMutableArray *collectionArray;
@end
@implementation ViewController
- (void)letItGo {
self.representativeImageArray = nil;
self.collectionArray = nil;
NSLog(@"Let go.");
}
- (void)viewDidLoad {
[super viewDidLoad];
self.representativeImageArray = [[NSMutableArray alloc]init];
self.collectionArray = [NSMutableArray arrayWithArray:[MPMediaQuery songsQuery].collections];
for(int i = 0; i < self.collectionArray.count; i++){
MPMediaItemCollection *collection = [self.collectionArray objectAtIndex:i];
for(int i1 = 0; i1 < collection.count; i1++){
MPMediaItem *representativeItem = [collection representativeItem];
UIImage *image = [representativeItem.artwork imageWithSize:CGSizeMake(500, 500)];
if(image){
[self.representativeImageArray addObject:image];
}
}
}
[NSTimer scheduledTimerWithTimeInterval:3.0
target:self
selector:@selector(letItGo)
userInfo:nil
repeats:NO];
NSLog(@"Got %ld items for collectionArray (%ld images).", self.collectionArray.count, self.representativeImageArray.count);
}
@end
对于从1214个项目(大小为500x500)生成的1210个图像,下面是运行一段时间后内存使用情况的图表:
与内存使用情况的图表相比,如果没有完全调用imageWithSize:
:
现在,我看到之前有人建议人们使用MPMediaItemArtwork
CGSize
bounds
属性UIImage *image = [representativeItem.artwork imageWithSize:CGSizeMake(500, 500)];
。所以,让我们这样做。
让我们改变
UIImage *image = [representativeItem.artwork imageWithSize:representativeItem.artwork.bounds.size];
到
json.encoder
现在,在运行与ViewController.m中相同的代码之后,通过这一次更改,我们得到了内存使用情况:
是的,与之前两次运行一样,与图像关联的阵列被删除了。虽然无论如何内存仍然保持在70 MB左右,并且似乎无法在不完全重新启动应用程序的情况下回到~10 MB。
这是我一整天都在努力解决的一个有趣问题。就个人而言,我更习惯于从C背景管理内存并且知道所有内存泄漏基本上都是我的错。对不起,如果这里的东西完全飞过我的脑袋。
非常感谢任何帮助,感谢您的阅读!