ios - 使用 ARC 进行内存分配 - 没有泄漏,但会慢慢堆积内存

标签 ios objective-c xcode memory-management automatic-ref-counting

我已经开始编写我第一次认真尝试为 iOS 混合的 Cordova/Objective-C 程序,我目前遇到了一些关于内存分配的绊脚石。我需要让用户的专辑封面显示在 WebView 中。我让艺术作品成功展示,但现在分配了大量内存。

使用“工具”工具并比较世代快照,我将我的罪魁祸首缩小到这些方法——我都是从头开始写的。但我很困惑——因为我使用的是自动引用计数,并且我在自动释放池中拥有所有东西,所以不应该有任何浪费的内存。有趣的是,我没有看到任何“泄漏”的报告——只是堆越来越大,分配的内存越来越多。

我附上了 Instruments 工具的一些截图:







由于文字太多,这里是图片的直接链接:

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 对象,这也可能是问题所在。

我真的可以在这方面使用一些帮助!谢谢!

最佳答案

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

如果它对你有任何帮助,我注意到如果你调用这个函数传入 artifact.bounds.size (而不是每次都创建一个新的图像大小),那么内存只会分配一次并再次调用 imageWithSize (具有相同的尺寸)不会重新分配新内存。仅当您传入原始艺术品图像的大小并且不返回自定义大小时,这似乎才是正确的。如果您需要自定义大小,也许您可​​以自己调整 UIImage 的大小,而不是依赖这种错误的方法。

关于ios - 使用 ARC 进行内存分配 - 没有泄漏,但会慢慢堆积内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31372597/

相关文章:

ios - 删除/停止 dispatch_async iOS

ios - 如何以编程方式从 UITableViewController 顺利过渡到 UIViewController

iphone - 如何在 iPhone 上创建 TableView 层次结构?

objective-c - 将用户发送到 App Store 以更新 OS X 版本

ios - ARC下使用Objective-C的method_invoke调用void方法

iphone - 使用蒙版从图像中裁剪字母

iOS 摇一摇手势 - 双摇

iphone - clang : error: no such file or directory:

ios - UITableViewCell 中的 Size 类自定义

ios - 解析 JSON 响应时 : fatal error: array cannot be bridged from Objective-C