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的大小,而不是依賴這個有問題的方法。