2014-12-13 87 views
0

我在释放分配时遇到问题。我的乐器中的分配工具表明“bitmapData = malloc(bitmapByteCount);”是分配的来源,并且不会被释放。我是可可和xcode的新手。我该如何纠正这个问题,并防止下面的代码使用越来越多的内存?我很感激帮助。由于创建不需要的分配/未能释放分配

#import "imagewell.h" 

@implementation imagewell 

- (id)initWithFrame:(NSRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     // Initialization code here. 



     NSString *path [email protected]"/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 space\n"); 
     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 

回答

0

如果malloc()内存,你(通常)负责后者呼吁free()将其释放。然而从CGBitmapContextCreate的文档:

在iOS系统4.0和更高版本,以及OS X v10.6中和后,你可以,如果你想石英为位图分配内存传递NULL。这使您免于管理自己的内存,从而减少内存泄漏问题。

所以在这种情况下,您应该能够删除malloc()并通过NULL

HTH

0

我无法释放CGImage对象。 释放它防止泄漏。 现在我避免了可用于多种方法的全局变量。