【发布时间】:2012-10-30 21:32:01
【问题描述】:
我正在使用以下代码在我的 iOS 应用程序的 touchesEnded 处截取绘图:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
if(_pagessavedbg.count > selectedIndex)
self.topimage = [_pagessavedbg objectAtIndex:selectedIndex];
else
self.topimage = [UIImage imageNamed:@"BlankImage.png"];
UIImage *bottomimage = [notification.userInfo objectForKey:@"Image"];
CGSize size = activeView.frame.size;
NSUInteger width = size.width * 2;
NSUInteger height = size.height * 2;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char *rawData = malloc(height * width * 4);
memset(rawData,0,height * width * 4);
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(rawData, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGRect bounds;
bounds.origin = CGPointMake(0,0);
bounds.size = size;
CGContextScaleCTM(context, 2.0, 2.0);
CGContextDrawImage(context, CGRectMake(0, 0, size.width, size.height), [self.topimage CGImage]);
CGContextDrawImage(context, CGRectMake(0, 0, size.width, size.height), [bottomimage CGImage]);
CGImageRef imageRef2 = CGBitmapContextCreateImage(context);
UIImage *latest2 = [UIImage imageWithCGImage:imageRef2 scale:0.0 orientation:UIImageOrientationDownMirrored];
activeView.layer.contentsScale = 2.0;
[activeView.layer renderInContext:context];
CGImageRef imageRef = CGBitmapContextCreateImage(context);
UIImage *latest = [UIImage imageWithCGImage:imageRef scale:0.0 orientation:UIImageOrientationDownMirrored];
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
CGImageRelease(imageRef);
CGImageRelease(imageRef2);
free(rawData);
[_pages replaceObjectAtIndex:_sidebar.selectedIndex withObject:latest];
[_sidebar reloadData];
if(_pages.count > selectedIndex)
{
if([_pages objectAtIndex:selectedIndex])
[_pages replaceObjectAtIndex:selectedIndex withObject:latest];
if([_pagessavedbg objectAtIndex:selectedIndex])
[_pagessavedbg replaceObjectAtIndex:selectedIndex withObject:latest2];
else
[_pagessavedbg insertObject:latest2 atIndex:selectedIndex];
}
dispatch_async(dispatch_get_main_queue(), ^{
[self.sidebar reloadData];
[self.sidebar scrollRowAtIndexToVisible:_sidebar.selectedIndex];
});
});
但是,每次调用此代码(在 touchesEnded 时),内存使用量都会增加大约 10MB。为什么会这样?有没有更好的替代方法可以使用更多更少的内存?
【问题讨论】:
-
您确实意识到这将创建原始图像数据的副本。对于视网膜 ipad,每像素 2048 * 1536 * 4 字节几乎正好是 12mb - 除了在渲染之前缩小视图之外,您无能为力。
-
所以我无法以任何方式减少如此巨大的内存使用量?
-
您所说的代码执行期间的内存使用情况不是内存泄漏对吗?
-
您可以消除图像的 Alpha 通道,这将减少 25% 或 3 MB 的内存使用量。将您的 malloc 更改为 (width * height * 3) 并相应地更改您的 bytesPerPixel 和 bytesPerRow。然后将最后的格式从 kCGImageAlphaPremultipliedLast 更改为 kCGImageAlphaNone。对这些确切的变化不是 100% 肯定,但这应该会让你走上正确的道路。
-
内存增加是由用于存储位图上下文数据的 malloc 引起的。原始图像使用大量数据,除了我上面提到的之外,你可以做的不多。
标签: iphone objective-c ios xcode memory-management