MPMediaItemArtwork imageWithSize:内存泄漏

时间:2016-10-13 19:43:59

标签: ios objective-c memory-leaks mpmediaitem

当在任何imageWithSize:对象上调用MPMediaItemArtwork时,即使已经删除了对关联的MPMediaItemUIImage的所有引用,内存仍然保持不变有一个神奇的参考抓住它。

我已经创建了一个完整的单独项目来测试这个特定的泄漏,我非常担心这是内部API的一个问题,而且我无能为力。

现在让我们进入一些好的事情。码。一个视图控制器和3个简单步骤将重现此问题。我的代码如下:

  1. 为图像创建一个数组,并获取一个MPMediaItemCollection个对象的数组(每个集合中只有一首歌,用于最坏情况的场景测试)
  2. 对于每个MPMediaItem中的每个代表MPMediaItemCollection,都会生成一张专辑图片,其中CGSize为500x500。
  3. 3秒后触发NSTimer,只会将与图像关联的所有数组设置为nil
  4. 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个图像,下面是运行一段时间后内存使用情况的图表:

    Memory use for 1210 images with imageWithSize

    与内存使用情况的图表相比,如果没有完全调用imageWithSize:

    enter image description here

    现在,我看到之前有人建议人们使用MPMediaItemArtwork CGSize bounds属性UIImage *image = [representativeItem.artwork imageWithSize:CGSizeMake(500, 500)]; 。所以,让我们这样做。

    让我们改变

    UIImage *image = [representativeItem.artwork imageWithSize:representativeItem.artwork.bounds.size];
    

    json.encoder

    现在,在运行与ViewController.m中相同的代码之后,通过这一次更改,我们得到了内存使用情况:

    enter image description here

    是的,与之前两次运行一样,与图像关联的阵列被删除了。虽然无论如何内存仍然保持在70 MB左右,并且似乎无法在不完全重新启动应用程序的情况下回到~10 MB。

    这是我一整天都在努力解决的一个有趣问题。就个人而言,我更习惯于从C背景管理内存并且知道所有内存泄漏基本上都是我的错。对不起,如果这里的东西完全飞过我的脑袋。

    非常感谢任何帮助,感谢您的阅读!

0 个答案:

没有答案