Objective c 如果已在scrollview外部引用,则scrollview中的set-UIImage:nil不会释放带有ARC的内存

Objective c 如果已在scrollview外部引用,则scrollview中的set-UIImage:nil不会释放带有ARC的内存,objective-c,memory-management,uiscrollview,uiimage,automatic-ref-counting,Objective C,Memory Management,Uiscrollview,Uiimage,Automatic Ref Counting,下面是我的应用程序的功能 它在启动时从服务器请求大约100个图像。它存储 模型对象中的那些图像,我们称之为modelObject.storedImage modelObject还有一个viewObject,它是UIImageView子类 该应用程序有一个2D scrollview,可将所有100个viewObjects设置为子视图,其中在任何给定时间,scrollview内容区域中最多显示16个 当您滚动到给定区域时,它会从相应的 modelObject.storedImage和Dos 当vie

下面是我的应用程序的功能

它在启动时从服务器请求大约100个图像。它存储 模型对象中的那些图像,我们称之为modelObject.storedImage modelObject还有一个viewObject,它是UIImageView子类 该应用程序有一个2D scrollview,可将所有100个viewObjects设置为子视图,其中在任何给定时间,scrollview内容区域中最多显示16个 当您滚动到给定区域时,它会从相应的 modelObject.storedImage和Dos

当viewObject滚动出内容区域时,它将从视图中清除

[modelObject.viewObject setImage:nil]; 
[modelObject.viewObject removeFromSuperview];
问题是,尽管进行了清除,但当您滚动到scrollview内容区域的新区域时,内存仍在不断增长。将以前的modelObject.viewObject.images放在scrollview上的内存没有释放。所以,如果你滚动到足够多的新区域,内存使用就会失控

需要说明的是,当应用程序首次将100幅图像加载到modelObject.storedImages中时,内存并没有失控。再者,如果我把这一点说出来

//modelObject.viewObject.image = modelObjects.storedImage;  
然后内存也会保持良好状态,但是滚动视图子视图当然不会显示任何图像

我确实看到了这个问题,但我相信它是不同的,因为在我的应用程序中,我无法不断地从服务器请求图像。一旦被请求,它们必须位于modelObject.storedImage,当相应的viewObject被滚动到时,它们总是准备好显示

肯定有办法告诉ARC释放这些nil图像的内存吗?提前感谢您的帮助

如果图像是由ImageName:创建的,则无法手动释放内存,您可以通过imageWithContentsOfFile对其进行优化,多亏您使用的是服务器图像,我认为您使用的是imageWithContentsOfFile.: 您可以尝试使用@autoreleasepool{}at滚动方法来实时释放内存。 您可以尝试释放viewObject而不是从SuperView中移除,可能您应该存储的是viewFrame而不是viewObject。
希望能给你一些帮助。

所以我绕过了这个问题,并以此作为解决方案。我很想知道是否有人有更有力的想法。我制作了一份图像副本,并将副本设置在scrollview上。现在,当我清除该副本时,它的内存实际上被释放了,谢谢!!,而原始图像仍然舒适地位于模型中。注意,简单地复制图像的CGImage并复制它是不可行的,在这种情况下内存不会释放。我必须使用UIGraphicsImageContext制作一个新副本

在Scrollview上设置图像的代码:

    UIImage *imageToCopy = modelObject.imageStore;
    CGSize size = imageToCopy.size;

    UIGraphicsBeginImageContext(size);
    [imageToCopy drawInRect:CGRectMake(0, 0, imageToCopy.size.width, imageToCopy.size.height)];
    UIImage *copiedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    [modelObject.viewObject setImage:copiedImage];
关闭scrollview内容区域时要清除的代码:

    [modelObject.viewObject setImage:nil];
    [modelObject.viewObject removeFromSuperview];
唯一的问题是绘制这些图像上下文使用了大量内存,因此我添加了此修改以使绘图更小:

    ...
    CGSize size = imageToCopy.size;
    size.width *= .2;
    size.height *= .2;

    UIGraphicsBeginImageContext(size);
    [imageToCopy drawInRect:CGRectMake(0, 0, imageToCopy.size.width*.2, imageToCopy.size.height*.2)];
    ...

非常感谢你的建议。以下是三个结果:1。实际上我没有创建映像,它是由AFNetworking在imageRequestOperationWithRequest:imageProcessingBlock:success:failure:2中作为UIImage提供的。尝试在一些地方添加@autoreleasepool{},但对3没有影响。如果我执行“[modelObject.viewObject发布];”我得到一个错误ARC禁止释放:/要在ARC中释放viewObject,您应该这样做:modelObject.viewObject=nil;Thx@Simone。但是,我尝试了modelObject.viewObject=nil;在清除中,当它滚动回该区域时,重新创建viewObject,如modelObject.viewObject=[[viewObject alloc]init];,但记忆仍然像以前一样增长。奇怪的是,即使我不重新创建viewObject,让它永远被清除,内存仍然会增长。在scrollview上设置一个图像,然后有完全不相关的引用指向它,这会泄漏内存,这是一个问题,我希望我在原始问题中已经描述过。
    ...
    CGSize size = imageToCopy.size;
    size.width *= .2;
    size.height *= .2;

    UIGraphicsBeginImageContext(size);
    [imageToCopy drawInRect:CGRectMake(0, 0, imageToCopy.size.width*.2, imageToCopy.size.height*.2)];
    ...