gpt4 book ai didi

ios - 关于 ARC 内存泄漏和不正确递减的 Xcode Analyzer 问题

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:33:50 27 4
gpt4 key购买 nike

我在我的项目中使用 ARC,但当我运行 Analyzer 时,我仍然遇到以下问题。

enter image description here

enter image description here

以下是我的代码:-

#import "UIImage+ImageSize.h"

@implementation UIImage (ImageSize)

- (CGRect)cropRectForImage:(UIImage *)image {

CGImageRef cgImage = image.CGImage;
CGContextRef context = [self createARGBBitmapContextFromImage:cgImage];
if (context == NULL) return CGRectZero;

size_t width = CGImageGetWidth(cgImage);
size_t height = CGImageGetHeight(cgImage);
CGRect rect = CGRectMake(0, 0, width, height);

CGContextDrawImage(context, rect, cgImage);

unsigned char *data = CGBitmapContextGetData(context);
CGContextRelease(context);

//Filter through data and look for non-transparent pixels.
int lowX = (int)width;
int lowY = (int)height;
int highX = 0;
int highY = 0;
if (data != NULL) {
for (int y=0; y<height; y++) {
for (int x=0; x<width; x++) {
int pixelIndex = (int)(width * y + x) * 4 /* 4 for A, R, G, B */;
if (data[pixelIndex] != 0) { //Alpha value is not zero; pixel is not transparent.
if (x < lowX) lowX = x;
if (x > highX) highX = x;
if (y < lowY) lowY = y;
if (y > highY) highY = y;
}
}
}
free(data);
} else {
return CGRectZero;
}

return CGRectMake(lowX, lowY, highX-lowX, highY-lowY);
}
- (CGContextRef)createARGBBitmapContextFromImage:(CGImageRef)inImage {

CGContextRef context = NULL;
CGColorSpaceRef colorSpace;
void *bitmapData;
int bitmapByteCount;
int bitmapBytesPerRow;

// Get image width, height. We'll use the entire image.
size_t width = CGImageGetWidth(inImage);
size_t height = CGImageGetHeight(inImage);

// Declare the number of bytes per row. Each pixel in the bitmap in this
// example is represented by 4 bytes; 8 bits each of red, green, blue, and
// alpha.
bitmapBytesPerRow = (int)(width * 4);
bitmapByteCount = (int)(bitmapBytesPerRow * height);

// Use the generic RGB color space.
colorSpace = CGColorSpaceCreateDeviceRGB();
if (colorSpace == NULL) return NULL;

// Allocate memory for image data. This is the destination in memory
// where any drawing to the bitmap context will be rendered.
bitmapData = malloc( bitmapByteCount );
if (bitmapData == NULL)
{
CGColorSpaceRelease(colorSpace);
return NULL;
}

// Create the bitmap context. We want pre-multiplied ARGB, 8-bits
// per component. Regardless of what the source image format is
// (CMYK, Grayscale, and so on) it will be converted over to the format
// specified here by CGBitmapContextCreate.
context = CGBitmapContextCreate (bitmapData,
width,
height,
8, // bits per component
bitmapBytesPerRow,
colorSpace,
kCGImageAlphaPremultipliedFirst);
if (context == NULL) free (bitmapData);

// Make sure and release colorspace before returning
CGColorSpaceRelease(colorSpace);
return context;
}

@end

我怎样才能让它正确?请帮助我理解这个问题是什么意思以及为什么会这样,因为我曾经认为 ARC 会自行处理所有内存清理问题。还有其他关于错误的 SO 问题几乎与此相同。但不在 CGContextRef 上。所以我不得不问一个新问题。

最佳答案

ARC 只处理对象指针类型和 block 指针类型。它不处理 Core Foundation 风格的引用类型(例如 CGContextRef)。

现在分析器问题。分析器(类似于 ARC)注意命名约定以确定方法或函数的行为方式。对于方法或函数的实现,它会检查其行为是否确实符合其命名约定。在调用站点,它假设它确实如此,然后检查周围的代码是否按照该假设运行。

现在,您可能知道 Core Foundation 有 "Create Rule"其中名称包含“Create”或“Copy”的函数通常返回 +1 引用,而其他函数通常返回 +0 引用(“获取规则”)。也许这就是为什么您将返回 CGContext 的方法命名为名称中包含“create”的原因。不幸的是,Core Foundation 规则不适用于 Objective-C 方法。

Cocoa 命名约定是名称以“alloc”、“new”、“copy”或“mutableCopy”开头的方法返回+1 引用。 (如果您没有使用 ARC,release 方法也会返回 +1 引用。)其他方法返回 +0 引用。

根据 Cocoa 命名约定,您的 -createARGBBitmapContextFromImage: 方法被假定为返回 +0 引用。但是,实际的实现返回一个 +1 引用。这是分析器报告的问题之一。然后,在调用站点,假定调用代码接收到 +0 引用。因此,它无权使用 CGContextRelease() 释放该引用。这是分析器报告的另一个问题。

您可以通过将 -createARGBBitmapContextFromImage: 重命名为 -newARGBBitmapContextFromImage: 来解决此问题。然后,根据 Cocoa 约定,它应该返回一个 +1 引用,并且实现和调用站点都将符合这个期望。

或者,您可以让 -createARGBBitmapContextFromImage: 执行 return (CGContextRef)CFAutorelease(context); 而不仅仅是 return context;。然后将调用者更改为不尝试释放上下文。在这种情况下,该方法的名称表明它返回一个 +0 引用,并且实现和调用站点都符合该引用。

关于ios - 关于 ARC 内存泄漏和不正确递减的 Xcode Analyzer 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42711256/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com