Objective-c内存警告

时间:2013-07-04 18:46:37

标签: objective-c

我正在尝试制作某种谜题,但是在5-10次洗牌后我收到了内存警告,现在我正在尝试添加谜题并将其从超级视图中移除但是,但是,仍然存在某种记忆韭菜..有人可以帮我吗?

- (void)setup6x6
{
    int num = 0;
    for (int i = 0; i < 6; i++)
    {
        for (int j = 0; j < 6; j++)
        {
            UIImageView * imgView = [[UIImageView alloc] init];

            cor = arc4random()%4;
            nCor = arc4random()%8;
            maxCor = arc4random()%16;

            scale = _pImage.size.width / puzzleArea.frame.size.width;
            NSString * imageName1;
            UIImage * imageToMask1;
            UIImage * maskedImage1;
            if (i == 0)
            {
                if (j == 0)
                {
                    imageName1 = [topLeftCornerPuzzles objectAtIndex:cor];
                    imageToMask1 = [self cropImage:_pImage withRect:CGRectMake(0,
                                                                              58 * i * scale,
                                                                              58 * scale,
                                                                              58 * scale)];
                }
                else if (j == 5)
                {
                    imageName1 = [self checkPreviousInArray6x6:puzzles new:[topRightCornerPuzzles objectAtIndex:cor] index:num];
                    imageToMask1 = [self cropImage:_pImage withRect:CGRectMake((42 + 50*(j-1)) * scale,
                                                                              58 * i * scale,
                                                                              58 * scale,
                                                                              58 * scale)];
                }
                else
                {
                    imageName1 = [self checkPreviousInArray6x6:puzzles new:[topPuzzles objectAtIndex:nCor] index:num];
                    imageToMask1 = [self cropImage:_pImage withRect:CGRectMake((42 + 50*(j-1)) * scale,
                                                                              58 * i * scale,
                                                                              66 * scale,
                                                                              58* scale)];
                }
            }
            else if (i < 5)
            {
                if (j == 0)
                {
                    imageName1 = [self checkPreviousInArray6x6:puzzles new:[leftPuzzles objectAtIndex:nCor] index:num];
                    imageToMask1 = [self cropImage:_pImage withRect:CGRectMake(0,
                                                                              (42 + 50*(i-1)) * scale,
                                                                              58 * scale,
                                                                              66 * scale)];
                }
                else if (j == 5)
                {
                    imageName1 = [self checkPreviousInArray6x6:puzzles new:[rightPuzzles objectAtIndex:nCor] index:num];
                    imageToMask1 = [self cropImage:_pImage withRect:CGRectMake((42 + 50*(j-1)) * scale,
                                                                              (42 + 50*(i-1)) * scale,
                                                                              58 * scale,
                                                                              66 * scale)];
                }
                else
                {
                    imageName1 = [self checkPreviousInArray6x6:puzzles new:[middlePuzzles objectAtIndex:maxCor] index:num];
                    imageToMask1 = [self cropImage:_pImage withRect:CGRectMake((42 + 50*(j-1)) * scale,
                                                                              (42 + 50*(i-1)) * scale,
                                                                              66 * scale,
                                                                              66 * scale)];
                }
            }
            else
            {
                if (j == 0)
                {
                    imageName1 = [self checkPreviousInArray6x6:puzzles new:[bottomLeftCornerPuzzles objectAtIndex:cor] index:num];
                    imageToMask1 = [self cropImage:_pImage withRect:CGRectMake(0,
                                                                              (42 + 50*(i-1)) * scale,
                                                                              58 * scale,
                                                                              58 * scale)];
                }
                else if (j == 5)
                {
                    imageName1 = [self checkPreviousInArray6x6:puzzles new:[bottomRightCornerPuzzles objectAtIndex:cor] index:num];
                    imageToMask1 = [self cropImage:_pImage withRect:CGRectMake((42 + 50*(j-1)) * scale,
                                                                              (42 + 50*(i-1)) * scale,
                                                                              58 * scale,
                                                                              58 * scale)];
                }
                else
                {
                    imageName1 = [self checkPreviousInArray6x6:puzzles new:[bottomPuzzles objectAtIndex:nCor] index:num];
                    imageToMask1 = [self cropImage:_pImage withRect:CGRectMake((42 + 50*(j-1)) * scale,
                                                                              (42 + 50*(i-1)) * scale,
                                                                              66 * scale,
                                                                              58 * scale)];
                }
            }
            [puzzles addObject:imageName1];
            maskedImage1 = [self maskImage:imageToMask1 withMask:[UIImage imageNamed:imageName1]];
            [imgView setImage:maskedImage1];

            if (i == 0)
                originY = 0;
            else
                originY = 50 * (i-1) + 42;

            if (j == 0)
                originX = 0;
            else
                originX = 50 * (j-1) + 42;

            if (j == 0 || j == 5)
                sizeW = 58;
            else
                sizeW = 66;

            if (i == 0 || i == 5)
                sizeH = 58;
            else
                sizeH = 66;

            [imgView setFrame:CGRectMake(originX, originY, sizeW, sizeH)];
            [puzzleArea addSubview:imgView];
            [imgView removeFromSuperview];
            //[maskedImage1 release];
            imageToMask1 = nil;
            maskedImage1 = nil;
            [imgView release];
            [imageName1 release];
            //[imageToMask1 release];
            num += 1;
        }
    }
}

我有如何裁剪:

- (UIImage *)cropImage:(UIImage *)image withRect:(CGRect)cropRect
{
    return [UIImage imageWithCGImage:CGImageCreateWithImageInRect(image.CGImage, cropRect)];
}

还有我掩饰的方式:

- (UIImage *)maskImage:(UIImage *)image withMask:(UIImage *)maskImg
{
    CGImageRef maskRef = maskImg.CGImage;
    CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
                                        CGImageGetHeight(maskRef),
                                        CGImageGetBitsPerComponent(maskRef),
                                        CGImageGetBitsPerPixel(maskRef),
                                        CGImageGetBytesPerRow(maskRef),
                                        CGImageGetDataProvider(maskRef),
                                        NULL,
                                        false);
    return [UIImage imageWithCGImage:CGImageCreateWithMask([image CGImage], mask)];
    CGImageRelease(maskRef);
    CGImageRelease(mask);
}

我无法理解为什么在发布所有内容时会收到内存警告。但是,如果我尝试释放maskedImage1或imageToMask1,我也会收到错误...

2 个答案:

答案 0 :(得分:1)

每次创建CGImage时,都需要发布它。 UIImage不会为您做到这一点。

如果您没有创建CGImage,则不应该发布CGImageRelease(maskRef)。在第二种方法中,您应执行return

当您从方法- (UIImage *)cropImage:(UIImage *)image withRect:(CGRect)cropRect { CGImageRef croppedCGImage = CGImageCreateWithImageInRect(image.CGImage, cropRect); UIImage *croppedUIImage = [UIImage imageWithCGImage:croppedCGImage]; CGImageRelease(croppedCGImage); return croppedUIImage; } - (UIImage *)maskImage:(UIImage *)image withMask:(UIImage *)maskImg { CGImageRef maskRef = maskImg.CGImage; CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef), CGImageGetHeight(maskRef), CGImageGetBitsPerComponent(maskRef), CGImageGetBitsPerPixel(maskRef), CGImageGetBytesPerRow(maskRef), CGImageGetDataProvider(maskRef), NULL, false); CGImageRef maskedCGImage = CGImageCreateWithMask([image CGImage], mask); UIImage *maskedUIImage = [UIImage imageWithCGImage:maskedCGImage]; CGImageRelease(maskedCGImage); CGImageRelease(mask); return maskedUIImage; } 时,不会执行该语句之后的代码。

{{1}}

答案 1 :(得分:1)

经验法则是“释放你拥有的一切”

每当您调用以alloccopynewretain开头的方法时,您都会获得对象的所有权(这些只是约定,但很多Objective-C是)。

每当您致电releaseautorelease时,您都会失去对象的所有权。

如果我们使用这些指南查看您的代码,您可以看到您发布了几个您从未拥有的对象。

  • 您正确alloc然后release imgView
  • 释放imageName1而不分配,复制或保留它。这可能会导致崩溃。 (我假设checkPreviousInArray6x6:new:index:没有返回它拥有的对象。)

对于MaskImage:withMask:,CG类型遵循类似的规则。

  • maskRef永远不会被保留,复制等,因此不应该被释放。
  • mask正在正确创建和发布。

然而,这个方法存在一个很大的问题:return之后的行永远不会被调用,因此内存永远不会被清除。

我建议在代码上运行静态分析器,因为它有很多错误可以帮助捕获。

有关手动内存管理的完整详细信息,建议您阅读Advanced Memory Management Programming Guide