2

我已经开始写我的第一个认真尝试在混合,科尔多瓦/目标C程序的iOS,我目前正在打击一些关于内存分配的绊脚石。我需要让用户的相册艺术才能在网页视图中显示。我获得了成功显示的艺术,但现在分配了大量内存。内存分配与ARC - 没有泄漏,但缓慢地堆积内存

使用“工具”工具和比较生殖快照,我将犯罪的罪魁祸首缩小到这些方法 - 我都是从头开始写的。但我很困惑 - 因为我使用自动引用计数,并且我拥有autorelease池中的所有内容,所以不应该有任何浪费的内存。有趣的是,我没有看到有报道称“泄漏” - 只是堆积越来越大,分配的内存越来越多。

我已经把它贴在仪器工具的一些截图:

这里是直接链接到图像,因为有这么多的文字:

http://i.imgur.com/rkc5dhA.png

http://i.imgur.com/U2esgBT.png

http://i.imgur.com/fmt3Mv4.png

下面是我做的 “BukketHelper.M” 类的内容(标题,没有强大的属性或任何种类的其他定义匹配):

-(NSString *) convertULLToNSString:(NSNumber*)guid 
{ 
    return [NSString stringWithFormat:@"%llu", [guid unsignedLongLongValue]]; 
} 

-(NSNumber *) convertStringToULL:(NSString *) guid 
{ 
    //get string to number 
    //this causes memory to not be released 
    unsigned long long ullvalue = strtoull([guid UTF8String], NULL, 10); 
    NSNumber *numberID = [[NSNumber alloc] initWithUnsignedLongLong:ullvalue]; 

    return numberID; 
} 

下面是我制作的“MediaQuery.M”类的内容(与标题完全匹配,没有强属性或其他定义):

-(MPMediaItem*) getMediaItemULL:(NSNumber*)guid 
{ 
    @autoreleasepool { 
     //run the query on 
     MPMediaQuery *query = [[MPMediaQuery alloc] init]; 
     [query addFilterPredicate:[MPMediaPropertyPredicate predicateWithValue:guid forProperty:MPMediaItemPropertyPersistentID]]; 

     //get and return the item 
     NSArray *mediaResults = [query items]; 
     return [mediaResults firstObject]; 
    } 
} 

-(MPMediaItem*) getMediaItem:(NSString*)guid 
{ 
    @autoreleasepool { 
     BukketHelper* bh = [[BukketHelper alloc] init]; 
     return [self getMediaItemULL:[bh convertStringToULL:guid]]; 
    } 
} 

-(UIImage*) getMediaAlbumArtAsUIImage:(NSString*)guid withQuality:(NSNumber*)quality withLength:(NSNumber*)length subsituteImageName:(NSString*)filename 
{ 
    return [self getMediaAlbumArtFromMediaItemAsUIImage:[self getMediaItem:guid] withQuality:quality withLength:length subsituteImageName:filename]; 
} 

-(NSString*) getMediaAlbumArtAsBase64:(NSString*)guid withQuality:(NSNumber*)quality withLength:(NSNumber*)length subsituteImageName:(NSString*)filename 
{ 
    NSString *base64 = nil; 

    @autoreleasepool { 
     UIImage* rawImage = [self getMediaAlbumArtAsUIImage:guid withQuality:quality withLength:length subsituteImageName:filename]; 
     NSData *imageData = nil; 

     if (rawImage != nil) 
     { 
      @autoreleasepool { 
       //this causes memory to not be released 
       imageData = UIImageJPEGRepresentation(rawImage, [quality floatValue]); 
       base64 = [imageData base64EncodedStringWithOptions:0]; 
      } 
     } 
    } 

    return base64; 
} 

-(UIImage*) getMediaAlbumArtFromMediaItemAsUIImage:(MPMediaItem*)item withQuality:(NSNumber*)quality withLength:(NSNumber*)length subsituteImageName:(NSString*)filename 
{ 
    UIImage *rawImage = nil; 

    @autoreleasepool { 
     bool successfulArt = NO; 

     if (item != nil) 
     { 
      MPMediaItemArtwork *albumArt = [item valueForProperty:MPMediaItemPropertyArtwork]; 

      if (albumArt != nil) { 
       @autoreleasepool { 
        //this causes memory to not be released 
        rawImage = [albumArt imageWithSize:CGSizeMake([length doubleValue], [length doubleValue])]; 
        successfulArt = YES; 
       } 
      } 
     } 

     if (successfulArt == NO) 
     { 
      rawImage = [UIImage imageNamed:filename]; 
     } 
    } 

    return rawImage; 
} 

所以是的 - 我的问题是:当我涉及内存分配和泄漏时,我做错了什么?我目前的测试是专门使用专辑封面 - 所以“UIImage imageNamed”不应该是问题(从它的缓存)。另外,我读过ARC不能发布CoreGraphics对象,这也可能是问题所在。

我真的可以用一些帮助!谢谢!

+1

您有足够的代表直接在帖子中包含图片 - 任何原因您没有使用该功能? – luk2302

+0

不知道该功能,也许;) –

+1

我编辑它们 - 你可以查看我的编辑,了解该功能:)实际上,您可能也想要显示该链接,因为它很难阅读,因为有很多文字 - 你的决定。 – luk2302

回答

0

我遇到了同样的问题。我认为在框架中存在一个不释放内存的错误。基本上每次调用func imageWithSize(size: CGSize) -> UIImage?时,分配的内存都会有一个巨大的高峰。

如果它对你有帮助,我注意到如果你调用这个函数传递的是artwork.bounds.size(而不是每次创建一个新的图像大小),那么内存只会被分配一次,并再次调用imageWithSize(with相同的尺寸)不会重新分配新的内存。如果您传递原始图稿图像的大小并且不返回自定义大小,这似乎是正确的。如果你需要一个自定义大小,也许你可以自己调整UIImage的大小,而不是依赖这个有问题的方法。