菜鸟教程小白 发表于 2022-12-13 07:06:47

ios - 如何释放不再使用的 UIImages 的内存


                                            <p><p>我正在尝试将一些较小的图像合并成一个较大的图像。应用程序因为内存不足而崩溃,但我不知道在使用后如何释放内存,所以它一直在累积直到应用程序崩溃。</p>

<p>addImageToImage 和 resizeImage 例程似乎导致了崩溃,因为在不再需要它们后我无法释放它们的内存。我在这个项目中使用自动引用计数。我尝试将图像设置为 nil,但这并不能阻止崩溃。</p>

<p>testImages 位于一个从主 ViewController 调用的类中,而 addImageToImage 和 resizeImage 位于另一个名为 ImageUtils 的类中。</p>

<p>有人可以看看这段代码并向我解释如何正确释放这两个例程分配的内存。由于项目使用 ARC 并将它们设置为 nil 无效,因此我无法在图像上调用 release。</p>

<pre><code>+ (void)testImages
    {
    const int IMAGE_WIDTH = 394;
    const int IMAGE_HEIGHT = 150;
    const int PAGE_WIDTH = 1275;
    const int PAGE_HEIGHT = 1650;
    const int COLUMN_WIDTH = 30;
    const int ROW_OFFSET = 75;

    CGSize imageSize = CGSizeMake(PAGE_WIDTH, PAGE_HEIGHT);
    UIGraphicsBeginImageContextWithOptions(imageSize, YES, 0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextFillRect(context, CGRectMake(0, 0, imageSize.width, imageSize.height));
    UIImage *psheet = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    CGSize collageSize = CGSizeMake(IMAGE_WIDTH, IMAGE_HEIGHT);
    UIGraphicsBeginImageContextWithOptions(collageSize, YES, 0);
    CGContextRef pcontext = UIGraphicsGetCurrentContext();
    CGContextFillRect(pcontext, CGRectMake(0, 0, collageSize.width, collageSize.height));
    UIImage *collage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();


    float row = 1;
    float column = 1;
    int index = 1;
    int group = 1;
    for (int i = 0; i &lt; 64; i++)
    {
      NSLog(@&#34;processing group %i - file %i &#34;, group, index++);

      psheet = ;


      column++;
      if (column &gt; 3) {
            column = 1;
            row++;
      }
      if (index == 15)
      {
            group++;
            index = 1;
            row = 1;
            column = 1;
            UIImage *editedImage = ;
            editedImage = nil;
      }
    }
}
</code></pre>

<p>ImageUtils 方法</p>

<pre><code>+(UIImage *) addImageToImage:(UIImage *)sheet withImage2:(UIImage *)label andRect:(CGRect)cropRect withImageWidth:(int) width withImageHeight:(int) height
{

    CGSize size = CGSizeMake(width,height);

    UIGraphicsBeginImageContext(size);

    CGPoint pointImg1 = CGPointMake(0,0);
    ;

    CGPoint pointImg2 = cropRect.origin;
    ;

    UIImage* result = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return result;

}

+ (UIImage*)resizeImage:(UIImage*)image withWidth:(CGFloat)width withHeight:(CGFloat)height
{
    CGSize newSize = CGSizeMake(width, height);
    CGFloat widthRatio = newSize.width/image.size.width;
    CGFloat heightRatio = newSize.height/image.size.height;

    if(widthRatio &gt; heightRatio)
    {
      newSize=CGSizeMake(image.size.width*heightRatio,image.size.height*heightRatio);
    }
    else
    {
      newSize=CGSizeMake(image.size.width*widthRatio,image.size.height*widthRatio);
    }


    UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
    ;
    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>也许您的图像没有被解除分配,而是移动到 <a href="https://developer.apple.com/library/mac/documentation/cocoa/conceptual/memorymgmt/articles/mmAutoreleasePools.html" rel="noreferrer noopener nofollow">autorelease pool</a> . </p>

<blockquote>
<p>Many programs create temporary objects that are autoreleased. These
objects add to the program’s memory footprint until the end of the
block. In many situations, allowing temporary objects to accumulate
until the end of the current event-loop iteration does not result in
excessive overhead; in some situations, however, you may create a
large number of temporary objects that add substantially to memory
footprint and that you want to dispose of more quickly. In these
latter cases, you can create your own autorelease pool block. At the
end of the block, the temporary objects are released, which typically
results in their deallocation thereby reducing the program’s memory
footprint</p>
</blockquote>

<p>尝试使用 <code>@autoreleasepool {}</code> 将代码包装在循环中:</p>

<pre><code>for (int i = 0; i &lt; 64; i++)
{
@autoreleasepool {
    NSLog(@&#34;processing group %i - file %i &#34;, group, index++);

    psheet = ;


    column++;
    if (column &gt; 3) {
      column = 1;
      row++;
    }
    if (index == 15)
    {
      group++;
      index = 1;
      row = 1;
      column = 1;
      UIImage *editedImage = ;
      editedImage = nil;
    }
}
}
</code></pre></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 如何释放不再使用的 UIImages 的内存,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/22584478/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/22584478/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 如何释放不再使用的 UIImages 的内存