2010-10-27 68 views
1

試圖找到我的代碼我刪除了所有無關緊要的東西泄漏,留下下面的代碼:泄漏在CGBitmapContextCreate

static int last_memory = 0; 

void report_memory(NSString *name) { 
    struct task_basic_info info; 
    mach_msg_type_number_t size = sizeof(info); 
    kern_return_t kerr = task_info(mach_task_self(), 
            TASK_BASIC_INFO, 
            (task_info_t)&info, 
            &size); 
    if(kerr == KERN_SUCCESS) { 
     int change = (int)info.resident_size - last_memory; 
     NSLog(@"%@ >>> Memory in use: %u (change: %d Kb)", name, info.resident_size, change/1024); 
     last_memory = info.resident_size; 
    } else { 
     NSLog(@"Error with task_info(): %s", mach_error_string(kerr)); 
    } 
} 

- (CGContextRef) createBitmapContextOfSize:(CGSize) size { 
    CGContextRef context = NULL; 
    CGColorSpaceRef colorSpace; 
    void *   bitmapData; 
    int    bitmapByteCount; 
    int    bitmapBytesPerRow; 

    bitmapBytesPerRow = (size.width * 4); 
    bitmapByteCount  = (bitmapBytesPerRow * size.height); 

    colorSpace = CGColorSpaceCreateDeviceRGB(); 
    bitmapData = malloc(bitmapByteCount); 
    if (bitmapData == NULL) { 
     NSLog(@"Memory not allocated!"); 
     CGColorSpaceRelease(colorSpace); 
     return NULL; 
    } 
    context = CGBitmapContextCreate (bitmapData, 
            size.width, 
            size.height, 
            8,  // bits per component 
            bitmapBytesPerRow, 
            colorSpace, 
            kCGImageAlphaPremultipliedLast); 
    CGContextSetAllowsAntialiasing (context,NO); 
    if (context== NULL) { 
     free (bitmapData); 
     CGColorSpaceRelease(colorSpace); 
     NSLog (@"Context not created!"); 
     return NULL; 
    } 
    CGColorSpaceRelease(colorSpace); 
    return context; 
} 

- (IBAction) clickButton:(UIButton *)sender { 
    report_memory(@"begin"); 
    NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"test"]; 
    UIImage *image = [UIImage imageWithContentsOfFile:path]; 

    report_memory(@"image_created"); 

    CGContextRef myBitmapContext = [self createBitmapContextOfSize:CGSizeMake(256, 256)]; 
    if (!myBitmapContext){ 
     return; 
    } 
    report_memory(@"bitmap_context_created"); 
    CGContextDrawImage(myBitmapContext, CGRectMake(0, 0, 256, 256), image.CGImage); 
    report_memory(@"draw_image"); 
    CGImageRef ref = CGBitmapContextCreateImage(myBitmapContext); 
    report_memory(@"image_context_created"); 
    CGContextRelease(myBitmapContext); 
    report_memory(@"bitmap_context_released"); 
    UIImage *result = [UIImage imageWithCGImage:ref]; 
    report_memory(@"image_created"); 
    CGImageRelease(ref); 
    report_memory(@"image_context_released"); 
    imageView.image = result; 
    report_memory(@"image_assigned"); 
} 

(「測試」是256×256的JPEG圖像)。 控制檯顯示點擊幾下後,以下:

begin >>> Memory in use: 18866176 (change: -12 Kb) 
image_created >>> Memory in use: 18870272 (change: 4 Kb) 
bitmap_context_created >>> Memory in use: 18870272 (change: 0 Kb) 
draw_image >>> Memory in use: 19140608 (change: 264 Kb) 
image_context_created >>> Memory in use: 19140608 (change: 0 Kb) 
bitmap_context_released >>> Memory in use: 19140608 (change: 0 Kb) 
image_created >>> Memory in use: 19140608 (change: 0 Kb) 
image_context_released >>> Memory in use: 19140608 (change: 0 Kb) 
image_assigned >>> Memory in use: 19140608 (change: 0 Kb) 

的256Kb的每次點擊成本(等於256x256x4)的淨虧損。分配績效工具中可以看到同樣的趨勢。指向CGBitmapContext的所有內容均未被釋放。我只是沒有看到我在做什麼錯...

回答

2

讓CGBitmapContextCreate通過提供NULL作爲第一個參數(bitmapData)來分配內存本身。這可以讓你免於管理你的內存分配 - 目前你還沒有釋放內存。

+0

非常感謝。從互聯網複製功能... – 2010-10-27 20:50:35