我在释放分配时遇到问题。我的工具中的分配工具指示"bitmapData = malloc( bitmapByteCount );"是分配的来源,并且没有被释放。我是可可和xcode的新手。我将如何纠正此问题并防止下面的代码使用越来越多的内存?我很感激你的帮助。谢谢
#import "imagewell.h"
@implementation imagewell
- (id)initWithFrame:(NSRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code here.
NSString *path =@"/Users/ethansanford/Desktop/mutable string logic/mutable string logic/long-arrow-right.png" ;
CGDataProviderRef provider = CGDataProviderCreateWithFilename(path.fileSystemRepresentation);
imageRef2 =CGImageCreateWithPNGDataProvider(provider, NULL, false, kCGRenderingIntentDefault);
CGDataProviderRelease(provider);
}
return self;
}
-(void)mouseDown:(NSEvent *)theEvent{
NSPoint point = [theEvent locationInWindow];//where image was tapped
[self convertPoint:point fromView:nil];
clicks = clicks+ 1;
colorpt=[self getPixelColorAtLocation:point];
[self SetPixelColorAtLocation:point withColor:[NSColor redColor]];
NSPoint pointz = NSPointFromCGPoint(CGPointMake(200, 100));
[self setNeedsDisplay:YES];
}
- (void)drawRect:(NSRect)dirtyRect{
CGContextRef myContext;
myContext = [NSGraphicsContext.currentContext graphicsPort];
imageRef = imageRef2;
// NSLog(@"%@ %zu",@"height",CGImageGetHeight(imageRef));
NSLog(@" %@ %f %f %f %f ", @"color1 argb", colorpt.alphaComponent*255, colorpt.redComponent*255, colorpt.greenComponent*255, colorpt.blueComponent*255);
CGContextSetFillColorWithColor(myContext, colorpt.CGColor);
CGRect rectangle = CGRectMake(0,0, 100, 100);
CGContextFillRect(myContext,rectangle);
CGContextDrawImage(myContext, dirtyRect, imageRef);
}
- (NSColor*) getPixelColorAtLocation:(NSPoint)point {
NSColor* color1 = nil;
// Create off screen bitmap context to draw the image into. Format ARGB is 4 bytes for each pixel: Alpa, Red, Green, Blue
CGContextRef cgctx = [self createARGBBitmapContextFromImage:imageRef];
if (cgctx == NULL) { return nil; /* error */ }
w = CGImageGetWidth(imageRef);
size_t h = CGImageGetHeight(imageRef);
CGRect rect = {{0,0},{w,h}};
// Draw the image to the bitmap context. Once we draw, the memory
// allocated for the context for rendering will then contain the
// raw image data in the specified color space.
CGContextDrawImage(cgctx, rect, imageRef);
// Now we can get a pointer to the image data associated with the bitmap
// context.
data = CGBitmapContextGetData (cgctx);
bitmap_info_of_context = CGBitmapContextGetBitmapInfo(cgctx);
bits_per_component_of_context = CGBitmapContextGetBitsPerPixel(cgctx);
bytes_per_row_of_context = CGBitmapContextGetBytesPerRow(cgctx);
width_of_context = CGImageGetWidth(imageRef);
height_of_context = CGImageGetHeight(imageRef);
if (data != NULL) {
//pos_in_array locates the pixel in the data from x,y.
//4 for 4 bytes of data per pixel, w is width of one row of data.
int pos_in_array = 4*((w*round(point.y))+round(point.x));
int alpha = data[pos_in_array];
int red = data[pos_in_array+1];
int green = data[pos_in_array+2];
int blue = data[pos_in_array+3];
//NSLog(@"pos_in_array: %i colors: RGB A %i %i %i %i",pos_in_array,red,green,blue,alpha);
color1 = [NSColor colorWithCalibratedRed:(red/255.0f) green:(green/255.0f) blue:(blue/255.0f) alpha:(alpha/255.0f)];
}
// When finished, release the context
CGContextRelease(cgctx);
// Free image data memory for the context
return color1;
}
- (CGContextRef) createARGBBitmapContextFromImage:(CGImageRef) imageRef {
CGContextRef context = NULL;
CGColorSpaceRef colorSpace;
void * bitmapData;
int bitmapByteCount;
int bitmapBytesPerRow;
// Get image width, height. We'll use the entire image.
size_t pixelsWide = CGImageGetWidth(imageRef);
size_t pixelsHigh = CGImageGetHeight(imageRef);
// 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 = (pixelsWide * 4);
bitmapByteCount = (bitmapBytesPerRow * pixelsHigh);
// Use the generic RGB color space.
colorSpace = CGColorSpaceCreateDeviceRGB();
if (colorSpace == NULL)
{
fprintf(stderr, "Error allocating color spacen");
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)
{
NSLog(@"%@", @"shit");
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,
pixelsWide,
pixelsHigh,
8, // bits per component
bitmapBytesPerRow,
colorSpace,
(CGBitmapInfo)kCGImageAlphaPremultipliedFirst);
if (context == NULL)
{
fprintf (stderr, "Context not created!");
}
// Make sure and release colorspace before returning
CGColorSpaceRelease( colorSpace );
return context;
CGContextRelease(context);
}
-(void)SetPixelColorAtLocation:(CGPoint)location withColor:(NSColor*)replacement{
if (data != NULL) {
//pos_in_array locates the pixel in the data from x,y.
//4 for 4 bytes of data per pixel, w is width of one row of data.
int pos_in_array = 4*((w*round(location.y))+round(location.x));
data[pos_in_array]= 255;
data[pos_in_array+1] = 0;
data[pos_in_array+2] = 255;
data[pos_in_array+3] = 0;
//NSLog(@"it happened");
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CGContextRef context= CGBitmapContextCreate(data, width_of_context, height_of_context, 8, bytes_per_row_of_context, colorspace, (CGBitmapInfo)kCGImageAlphaPremultipliedFirst);
imageRef2 = CGBitmapContextCreateImage(context);
CGColorSpaceRelease(colorspace);
CGContextRelease(context);
}
}
@end
malloc()
内存,你(通常)负责后者调用free()
来释放它。但是,从CGBitmapContextCreate
的文档来看:
在 iOS 4.0 及更高版本以及 OS X v10.6 及更高版本中,如果您希望 Quartz 为位图分配内存,则可以传递 NULL。这使您无需管理自己的内存,从而减少内存泄漏问题。
因此,在这种情况下,您应该能够删除malloc()
并通过 NULL
.
呵
我未能释放CGImage对象。释放它防止了泄漏。我现在避免了可以在多种方法中使用的全局变量。