我使用简单的位图技术将文本转换为图像,之后我将此图像划分为栅格,之后我计算每个栅格矩形中黑色像素的百分比。每个东西在模拟器上工作正常但在Device上崩溃了。这是一些相关的代码
-(int)blackValue:(UIImage *)image rect:(CGRect)rect {
int pixelInRect = (int)rect.size.width * rect.size.height;
__block int blackCount = 0;
ImageBitmap * imageBitmap = [[ImageBitmap alloc] initWithImage:image bitmapInfo:(CGBitmapInfo)kCGImageAlphaNoneSkipLast];
for (int x = 0; x <(int) rect.size.width; x++) {
for (int y = 0; y < (int) rect.size.height; y++) {
Byte * pixel = [imageBitmap pixelAtX:(int)rect.origin.x Y:(int)rect.origin.y];
Byte red = pixel[0];
if (red < 0.1)
{
blackCount++;
}
}
}
return blackCount/pixelInRect;
}
- (NSDictionary *)rasterizeBitmap:(UIImage *)image size:(CGFloat)size {
CGFloat width =(int) (image.size.width/size);
CGFloat height =(int) (image.size.height/size);
NSMutableArray *fields = [NSMutableArray array];
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
CGRect rect = CGRectMake(x * size, y * size, size, size);
CGPoint center = CGPointMake(x * size + size/2.0, image.size.height - (y * size + size/2.0));
double black = [self blackValue:image rect:rect];
Field * field = [[Field alloc] init];
field.center = center;
field.black = black;
[fields addObject:field];
}
}
return @{@"width":@(width) , @"fields":fields};
}
当我尝试在Profile中运行它时,得到了以下结果
有人可以建议我如何解决内存问题?
答案 0 :(得分:3)
ImageBitmap
对象中手动分配内存,但是你永远不会释放它。两个嫌疑人是位图上下文(context
)和位图数据(contextData
)。这两个都不是由ARC管理的,所以一旦你完成它们,你就会想要自己解放这两个。
在ARC中,您只需在dealloc
类中实现ImageBitmap
方法,并将清理代码放在那里。
例如:
-(void) dealloc {
CGContextRelease(context); // releases the bitmap context, if it was created (CGContextRelease checks for NULL)
free(contextData); // releases the bitmap data (it was explicitly created, so no need to check)
}
init
不可用,并标记您指定的初始值。这是因为无法使用您的imageFromContext
和pixelAtX:Y:
实例方法,而无需通过自定义initWithSize:bitmapInfo:
初始化程序创建实例,因为它会创建位图上下文并为位图数据分配内存。
因此,如果您要通过调用init
来创建实例,并调用其中一个实例方法,则很可能会崩溃。
要解决此问题,您可以在init
文件中将ImageBitmap.h
方法标记为不可用,并将initWithSize:bitmapInfo:
方法标记为指定的初始值。
-(instancetype) init NS_UNAVAILABLE;
-(id)initWithSize:(CGSize)size bitmapInfo:(CGBitmapInfo)bmInfo NS_DESIGNATED_INITIALIZER;
所有NS_UNAVAILABLE
所做的就是阻止您通过调用init
来创建实例,从而强制您使用自定义初始化工具。
如果您尝试执行[[ImageBitmap alloc] init]
,编译器将显示以下错误:
NS_DESIGNATED_INITIALIZER
所做的只是确保ImageBitmap
中的任何额外初始化工具必须通过初始化工具创建新实例,并且如果他们不知道,则会显示以下警告:
See here for more info on NS_DESIGNATED_INITIALIZER
.
现在,实际上这些只是手续,因为您是唯一一个将要使用此功能的人,并且您知道必须使用自定义初始化程序。但是,如果您想与其他人分享您的代码,那么获得这些手续是正确的。