【发布时间】:2020-06-14 10:38:50
【问题描述】:
当我想创建一个 NSImage 对象时,我遇到了内存泄漏。我通过以下方式编译了代码:
clang -o test test.m -framework Foundation -fsanitize=leak -framework CoreGraphics -framework AppKit,我用的clang就是这样的:gist
// test.m
#include <Foundation/Foundation.h>
#include <Foundation/NSURL.h>
#include <dlfcn.h>
#include <stdint.h>
#include <sys/shm.h>
#include <dirent.h>
#import <Cocoa/Cocoa.h>
#import <ImageIO/ImageIO.h>
int main(int argc, const char * argv[]) {
if (argc < 2) {
printf("Usage: %s path/to/image\n", argv[0]);
return 0;
}
NSString* path = [NSString stringWithUTF8String:argv[1]];
NSData* content = [NSData dataWithContentsOfFile:path];
while(true) {
NSImage* img = [[NSImage alloc] initWithData:content];
[img release];
}
[content release];
[path release];
return 0;
}
然后我通过./test test.tiff调用它,asan报错initWithData有内存泄漏。
如果在while循环中运行,内存消耗不断增加。
它适用于@Asperi 提供的答案。但是当我想做更多与NSImage相关的工作时,像这样:这段代码会崩溃,因为CGImageRelease(cgImg);和[img release];不能同时启用。但是如果我禁用其中一个,代码不会崩溃,但内存消耗会不断增加。
#include <Foundation/Foundation.h>
#include <Foundation/NSURL.h>
#include <dlfcn.h>
#include <stdint.h>
#include <sys/shm.h>
#include <dirent.h>
#import <Cocoa/Cocoa.h>
#import <ImageIO/ImageIO.h>
int main(int argc, const char * argv[]) {
if (argc < 2) {
printf("Usage: %s path/to/image\n", argv[0]);
return 0;
}
NSString* path = [NSString stringWithUTF8String:argv[1]];
NSData* content = [NSData dataWithContentsOfFile:path];
while(true) {
@autoreleasepool {
NSImage* img = [[NSImage alloc] initWithData:content];
NSLog(@"Image @ %p: %@\n", img, img);
CGImageRef cgImg = [img CGImageForProposedRect:nil context:nil hints:nil];
if (cgImg) {
size_t width = CGImageGetWidth(cgImg);
size_t height = CGImageGetHeight(cgImg);
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CGContextRef ctx = CGBitmapContextCreate(0, width, height, 8, 0, colorspace, 1);
CGRect rect = CGRectMake(0, 0, width, height);
CGContextDrawImage(ctx, rect, cgImg);
CGColorSpaceRelease(colorspace);
CGContextRelease(ctx);
CGImageRelease(cgImg);
}
[img release];
}
}
[content release];
[path release];
return 0;
}
【问题讨论】:
标签: objective-c memory-leaks nsimage