简体   繁体   English

iOS 8.1 iPad Air 2 - 图像加载内存错误

[英]iOS 8.1 iPad Air 2 - Image loading memory error

To try to explain the problem as succinctly as possible.. I have written an app that force-loads a sequence of very large png's into memory using multithreading with Grand Central Dispatch, into a UIImageView animation sequence. 试图尽可能简洁地解释问题..我编写了一个应用程序,使用Grand Central Dispatch多线程将一系列非常大的png强制加载到内存中,形成UIImageView动画序列。 Have been testing until recently on the iPad Air 1 (with its 1GB of RAM), whereby I could only get approximately 40 of these 1.7MB images loaded into memory before the app would crash. 直到最近才测试iPad Air 1(带有1GB内存),在应用程序崩溃之前,我只能将大约40个这些1.7MB图像加载到内存中。 Fair enough. 很公平。 But now with the iPad Air 2 I was eager to get my hands on the 2GB of RAM which should easily be enough to get my entire sequence of 180 x 1.7MB png images (yes, I know, but just run with me on this) fully into memory, and then some. 但现在有了iPad Air 2,我很想把手放在2GB的RAM上,这应该足以让我获得180 x 1.7MB png图像的整个序列(是的,我知道,但只是跟我一起跑)完全进入记忆,然后一些。 But to my dismay it only seems to be able to get up to 111 of them into memory before crashing with the following error in the console; 但令我沮丧的是,它似乎只能在控制台中出现以下错误之前将其中的111个放入内存中;

-[_CSIRenditionBlockData _allocateImageBytes] Allocation of image block data with for CoreUI Rendition failed 2014-10-24 20:21:55.592 TestApp[280:19701] CoreUI: Error while decoding CSI/ZIP compressed image block data (rows 1280 rowbytes 10240 format 0) - [_ CSIRenditionBlockData _allocateImageBytes]用于CoreUI Rendition的图像块数据分配失败2014-10-24 20:21:55.592 TestApp [280:19701] CoreUI:解码CSI / ZIP压缩图像块数据时出错(行1280行字节10240格式0 )

The 2GB ram should definitely be able to handle the full sequence of images, three times over, surely? 2GB内存肯定能够处理完整的图像序列,三次,当然? What does the above error allude to? 上述错误提到了什么? Can anyone help? 有人可以帮忙吗? I really want the Air 2 to hit this out of the park and so far, I've stumbled out of the gate.. 我真的希望Air 2能够从公园里出来,到目前为止,我已经跌跌撞撞了。

The forced image-loading code is performed with this method; 使用该方法执行强制图像加载代码;

+ (UIImage*)imageImmediateLoadWithContentsOfFile:(NSString*)path {

    UIImage* image = [UIImage imageWithContentsOfFile:path];

    CGFloat w = image.size.width;
    CGFloat h = image.size.height;

    CGFloat scale = image.scale;

    if (image.scale > [[UIScreen mainScreen] scale]) {

        scale = 1.0f;

    } else {

        //NSLog(@"SCREEN SCALE LEAVE ALONE\n");
    }

    CGImageRef cgImage = [image CGImage];

    CGContextRef context = CGBitmapContextCreate(NULL, w*scale, h*scale, CGImageGetBitsPerComponent(cgImage), CGImageGetBytesPerRow(cgImage), CGImageGetColorSpace(cgImage), kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little);

    CGContextDrawImage(context, CGRectMake(0, 0, w*scale, h*scale), cgImage);

    CGImageRef decompressedImageRef = CGBitmapContextCreateImage(context);
    UIImage* forcedImage = [UIImage imageWithCGImage:decompressedImageRef scale:scale orientation:UIImageOrientationUp];

    CGImageRelease(decompressedImageRef);

    CGContextRelease(context);

    return forcedImage;

}

Grand Central Dispatch is used with dispatch_apply in the following function; Grand Central Dispatch与dispatch_apply一起用于以下函数;

- (void)startImageLoading {

    dispatch_group_async(hardloadGroup, concurrentBackgroundQueue, ^{

        if (abort) return;

        if (targetSlot == 1 || targetSlot == 3) {

            updateLoadingBar = YES;
            loadingProgress = 0.0f;
            loadingIncrement = 1.0f/(float)framecount;

        }

        dispatch_apply(framecount/FLICKBOOK_STRIDE, concurrentBackgroundQueue, ^(size_t i) {

            if (abort) return;

            size_t current = i * FLICKBOOK_STRIDE + 1;
            size_t end = current + FLICKBOOK_STRIDE;

            do {

                if (updateLoadingBar) [self incrementLoadingBar];

                [self hardloadImageForFrame:current++];

            } while (current < end && !abort);

        });

        if (!abort) {

            // MOP-UP ANY LEFTOVER FRAMES AFTER THE STRIDE DIVISION /////////////////////////////////////////////////////////

            for (size_t i = framecount - (framecount % FLICKBOOK_STRIDE) + 1; i <= framecount; i++) {

                if (abort) break;

                if (updateLoadingBar) [self incrementLoadingBar];

                [self hardloadImageForFrame:i];

            }

        }

    });

    // WRITE THE CONTENTS OF THE DICTIONARY TO THE IMAGE ARRAY IN ORDER /////////////////////////////////////////////

    dispatch_group_notify(hardloadGroup, concurrentBackgroundQueue, ^{

        if (!abort) [self performSelectorOnMainThread:@selector(showFlickbook) withObject:nil waitUntilDone:YES];

        [showcaseViewController loadingThreadFinished];

    });

}


- (void)hardloadImageForFrame:(size_t)frame {

    UIImage* forcedImage = [UIImage imageImmediateLoadWithContentsOfFile:[imageNames objectAtIndex:frame-1]];

    @synchronized(self) { [imageArray replaceObjectAtIndex:frame withObject:forcedImage]; }

}

Does anyone know what's causing the problem? 有谁知道是什么导致了这个问题?

Well, the error is clearly a memory allocation problem. 好吧,错误显然是内存分配问题。 It looks like you are decompressing those 1.7Mb png files into around 12.5Mb each (in the error - 1280 rows each of 10240 bytes). 看起来你正在将这些1.7Mb的png文件解压缩到大约每个12.5Mb(在错误中 - 每个1240行10240字节)。 And 111 lots of 12.5Mb is going to use around 1.4Gb. 111批12.5Mb将使用大约1.4Gb。 So I think you have hit the maximum you can load, given that iOS and other apps will be using some of that 2Gb. 因此,我认为你已经达到了可以加载的最大值,因为iOS和其他应用程序将使用一些2Gb。

Not sure why you are "forceLoading these" - presumably it's a performance issue? 不知道你为什么“强行加载这些” - 可能是性能问题? Do you know whether the time consuming bit comes from reading in the file, or from decompressing the png? 你知道这个耗时的部分是来自读取文件还是解压缩png? If the former, you could try pre-loading the files as NSData objects, and then using UIImage's imageWithData: method or CGImageSourceCreateWithData to build the images on the fly. 如果是前者,您可以尝试将文件预先加载为NSData对象,然后使用UIImage的imageWithData:方法或CGImageSourceCreateWithData来动态构建图像。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM