我收到内存错误。我收到内存错误,因为内存使用量呈指数级增长。很明显,我没有发布任何想法可能是什么?
这是我确定UI图像中存在的红色像素的方法。它返回计数。
- (NSUInteger)getRedPixelCount:(UIImage*)image
{
NSUInteger numberOfRedPixels = 0;
struct pixel* pixels = (struct pixel*) calloc(1, image.size.width * image.size.height * sizeof(struct pixel));
if (pixels != nil)
{
CGContextRef context = CGBitmapContextCreate((void *) pixels,
image.size.width,
image.size.height,
8,
image.size.width * 4,
CGImageGetColorSpace(image.CGImage),
(CGBitmapInfo)kCGImageAlphaPremultipliedLast);
if (context != NULL)
{
CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, image.size.width, image.size.height), image.CGImage);
NSUInteger numberOfPixels = image.size.width * image.size.height;
while (numberOfPixels > 0) {
if (pixels->r == 255) {
numberOfRedPixels++;
}
pixels++;
numberOfPixels--;
}
CGContextRelease(context);
}
}
return numberOfRedPixels;
}
这是迭代照片库图像并确定每个红色像素的代码。
[self.library enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
if (group) {
[group setAssetsFilter:[ALAssetsFilter allPhotos]];
[group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop){
if (asset) {
ALAssetRepresentation *rep = [asset defaultRepresentation];
CGImageRef iref = [rep fullResolutionImage];
if (iref){
UIImage *myImage = [UIImage imageWithCGImage:iref scale:[rep scale] orientation:(UIImageOrientation)[rep orientation]];
NSLog(@"%i", [self getRedPixelCount:myImage]);
}
}
}];
}
} failureBlock:^(NSError *error) {
NSLog(@"error enumerating AssetLibrary groups %@\n", error);
}];
此致 下进行。
答案 0 :(得分:1)
您没有释放
分配的内存struct pixel* pixels = (struct pixel*) calloc(1, image.size.width * image.size.height * sizeof(struct pixel));
您需要添加:
free(pixels);
位于if(pixels!= nil)块的底部。
使第一个块看起来像:
- (NSUInteger)getRedPixelCount:(UIImage*)image
{
NSUInteger numberOfRedPixels = 0;
struct pixel* pixels = (struct pixel*) calloc(1, image.size.width * image.size.height * sizeof(struct pixel));
if (pixels != nil)
{
CGContextRef context = CGBitmapContextCreate((void *) pixels,
image.size.width,
image.size.height,
8,
image.size.width * 4,
CGImageGetColorSpace(image.CGImage),
(CGBitmapInfo)kCGImageAlphaPremultipliedLast);
if (context != NULL)
{
CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, image.size.width, image.size.height), image.CGImage);
NSUInteger numberOfPixels = image.size.width * image.size.height;
struct pixels* ptr = pixels;
while (numberOfPixels > 0) {
if (ptr->r == 255) {
numberOfRedPixels++;
}
ptr++;
numberOfPixels--;
}
CGContextRelease(context);
}
free(pixels);
}
return numberOfRedPixels;
}
如果第二个块改为包括:
,它也会有所帮助 @autoreleasepool {
ALAssetRepresentation *rep = [asset defaultRepresentation];
CGImageRef iref = [rep fullResolutionImage];
if (iref){
UIImage *myImage = [UIImage imageWithCGImage:iref scale:[rep scale] orientation:(UIImageOrientation)[rep orientation]];
NSLog(@"%i", [self getRedPixelCount:myImage]);
<#statements#>
}
}
虽然主要泄漏没有释放像素缓冲区。
答案 1 :(得分:0)
您可以使用@autorelease:
包含'enumerateAssetsUsingBlock'块@autorelease {
if (asset) {
...
}
}
这会强制立即释放所有自动释放对象。
UPD: 使用[资产缩略图]而不是fullScreenImage或fullResolutionImage。这些方法会产生大量的像素数据。
UPD2: 如果甚至[资产缩略图]没有帮助,你必须找到一种方法来释放这个图像数据,只要你不能直接调用CGImageRelease释放它就可能有点棘手。尝试这样的事情:
NSMutabelArray* arr = [NSMutabelArray new];
在你的enumerateAssetsUsingBlock中,只需将资产对象放在这个数组中:
[arr addObject:asset];
在这个街区别无其他。
然后以某种方式遍历此数组:
while (arr.count > 0)
{
ALAsset* asset = [arr lastObject];
// do smth with asset
[arr removeLastObject]; // this will remove object from memory immediatelly
}