我创建的iPad应用程序必须能够为我之前在应用程序中生成的4096x2992图像创建图块。
4096x2992图像不是很复杂(我正在测试),当以png格式写入文件时大约是600kb ......
在模拟器上,这段代码似乎工作正常,但是当我在更严格的内存条件下运行应用程序时(在我的iPad上),这个过程会因为内存不足而退出...
我以前在应用程序中使用了相同的代码,但工作正常(但只为3072x2244图像创建了图块)...
要么我必须做一些愚蠢的错误或我的@ autoreleasepool's不能正常工作(我想我提到我使用ARC)...当在乐器中运行时我只能看到使用的内存爬上直到〜 500mb然后崩溃!
我已经分析了代码并且没有发现与我的应用程序的这一部分相关的单个内存泄漏所以我真的很困惑为什么这会让我崩溃......
关于我的函数如何被调用的一点历史,所以你知道发生了什么......应用程序使用CoreGraphics渲染UIView(4096x2992),其中包含一些UIImageView然后它将UIImage引用发送到我的函数{{1} }(下面)它开始切割/调整图像大小以创建我的文件......
以下是buildFromImage:
代码......内存问题是在buildFromImage:
下的主循环内构建的......
NSLog(@"LOG ------------> Begin tile loop ");
以下是我的调整大小/裁剪功能,因为这些也可能导致问题..
-(void)buildFromImage:(UIImage *)__image {
NSLog(@"LOG ------------> Begin Build ");
//if the __image is over 4096 width of 2992 height then we must resize it! (stop crashes ect)
if (__image.size.width > __image.size.height) {
if (__image.size.width > 4096) {
__image = [self resizeImage:__image toSize:CGSizeMake(4096, (__image.size.height * 4096 / __image.size.width))];
}
} else {
if (__image.size.height > 2992) {
__image = [self resizeImage:__image toSize:CGSizeMake((__image.size.width * 2992 / __image.size.height), 2992)];
}
}
//create preview image (if landscape, no more than 748 high... if portrait, no more than 1004 high) must keep scale
NSString *temp_archive_store = [[NSString alloc] initWithFormat:@"%@/%i-temp_imgdat.zip",NSTemporaryDirectory(),arc4random()];
NSString *temp_tile_store = [[NSString alloc] initWithFormat:@"%@/%i-temp_tilestore/",NSTemporaryDirectory(),arc4random()];
//create the temp dir for the tile store
[[NSFileManager defaultManager] createDirectoryAtPath:temp_tile_store withIntermediateDirectories:YES attributes:nil error:nil];
//create each tile and add it to the compressor once its made
//size of tile
CGSize tile_size = CGSizeMake(256, 256);
//the scales that we will be generating the tiles too
NSMutableArray *scales = [[NSMutableArray alloc] initWithObjects:[NSNumber numberWithInt:1000],[NSNumber numberWithInt:500],[NSNumber numberWithInt:250],[NSNumber numberWithInt:125], nil]; //scales to loop round over
NSLog(@"LOG ------------> Begin tile loop ");
@autoreleasepool {
//loop through the scales
for (NSNumber *scale in scales) {
//scale the image
UIImage *imageForScale = [self resizedImage:__image scale:[scale intValue]];
//calculate number of rows...
float rows = ceil(imageForScale.size.height/tile_size.height);
//calulate number of collumns
float cols = ceil(imageForScale.size.width/tile_size.width);
//loop through rows and cols
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
NSLog(@"LOG ------> Creating Tile (%i,%i,%i)",col,row,[scale intValue]);
//build name for tile...
NSString *tile_name = [NSString stringWithFormat:@"%@_%i_%i_%i.png",@"image",[scale intValue],col,row];
@autoreleasepool {
//build tile for this coordinate
UIImage *tile = [self tileForRow:row column:col size:tile_size image:imageForScale];
//convert image to png data
NSData *tile_data = UIImagePNGRepresentation(tile);
[tile_data writeToFile:[NSString stringWithFormat:@"%@%@",temp_tile_store,tile_name] atomically:YES];
}
}
}
}
}
}
现在我从来没有用过那么好的内存管理,所以我确实花时间阅读它并将我的项目转换为ARC以查看是否可以解决我的问题(那是前一段时间)但是我在仪器中对其进行分析后得到的结果我必须做一些愚蠢的错误,因为内存泄漏就像它那样糟糕但我只是看不出我做错了什么。
如果有人能指出我可能做错的事情,那就太好了!
由于
利安
(如果您需要更多信息,请告诉我)
答案 0 :(得分:0)
我使用“UIImage + Resize”。在@autoreleasepool {}里面,它可以在循环中使用ARC。
https://github.com/AliSoftware/UIImage-Resize
-(void)compress:(NSString *)fullPathToFile {
@autoreleasepool {
UIImage *fullImage = [[UIImage alloc] initWithContentsOfFile:fullPathToFile];
UIImage *compressedImage = [fullImage resizedImageByHeight:1024];
NSData *compressedData = UIImageJPEGRepresentation(compressedImage, 75.0);
[compressedData writeToFile:fullPathToFile atomically:NO];
}
}