Когда я хочу создать объект NSImage, я столкнулся с утечкой памяти. Я скомпилировал код следующим образом: clang -o test test.m -framework Foundation -fsanitize=leak -framework CoreGraphics -framework AppKit
, использованный мной лязг был таким: 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
имеет утечку памяти. Если он работает при l oop, потребление памяти продолжает увеличиваться.
Работает с ответом, предоставленным @Asperi. Но когда я хочу сделать больше работ, связанных с NSImage, например: этот код будет обрабатывать sh, потому что CGImageRelease(cgImg);
и [img release];
не могут быть включены в это время. Но если я отключу один из них, код не взломает sh, но потребление памяти будет увеличиваться.
#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;
}