2013-02-22 32 views
1

我的應用程序在UIImageView中分配並顯示圖像。這發生在24個imageViews全部在viewDidLoad。圖像從50張圖像列表中隨機分配。視圖控制器從主屏幕模態地推動。第一次加載需要一段時間。如果我很幸運,視圖會再次加載。第三次,它幾乎總是崩潰。我嘗試將圖像大小調整爲200像素左右。我試着將圖像生成:目標C內存崩潰,UIImageView

image1 = [UIImage imageNamed:@"image1.png"]; 

    [self.imageView setImage: image1]; 

,並與:

NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"image1" ofType:@"png"]; 

    image1 = [[UIImage alloc] initWithContentsOfFile:imagePath]; 

這第二個似乎只會使事情變得更糟。

我也試着用Instruments運行應用程序,它沒有識別任何內存泄漏。

我真的不知道還有什麼地方可以轉。這個程序表示巨大投資的時候,我真的想看到這個問題得到解決...... 謝謝你這麼多

+0

你會收到內存警告嗎? – 2013-02-22 02:15:52

+0

是的,我會收到內存警告,然後下次我嘗試加載視圖時,它會崩潰。 – user2014741 2013-02-22 02:17:23

+1

這次崩潰是因爲你加載了太多的大圖片,並且內存超出了ios允許的範圍 – 2013-02-22 02:20:53

回答

1

我有一次圖像之前有這個問題從一個普通的網站,是這樣大比我使用的視圖。如果我沒有記錯的話,這些圖像將被解壓縮到其全分辨率,然後進入圖像視圖,從而佔用您的內存。在展示它們之前,我必須首先將它們縮小到圖像視圖大小。添加CoreGraphics.framework並使用這個類來創建一個圖像對象以用於圖像視圖。我在網上找到它,稍微調整了一下,找到相同的答案,但不記得在哪裏,所以感謝發佈原件的人,無論他們是誰。

ImageScale.h

#import <Foundation/Foundation.h> 

@interface ImageScale : NSObject 

+ (UIImage*)imageWithImage:(UIImage*)sourceImage scaledToSize:(CGSize)newSize; 

@end 

ImageScale.m

#import "ImageScale.h" 

@implementation ImageScale 

+ (UIImage*)imageWithImage:(UIImage*)sourceImage scaledToSize:(CGSize)newSize 
{ 
    CGFloat targetWidth = newSize.width; 
    CGFloat targetHeight = newSize.height; 

    CGImageRef imageRef = [sourceImage CGImage]; 
    CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef); 
    CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef); 

    if (bitmapInfo == kCGImageAlphaNone) { 
     bitmapInfo = kCGImageAlphaNoneSkipLast; 
    } 

    CGContextRef bitmap; 

    if (sourceImage.imageOrientation == UIImageOrientationUp || sourceImage.imageOrientation == UIImageOrientationDown) { 
     bitmap = CGBitmapContextCreate(NULL, targetWidth, targetHeight, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo); 

    } else { 
     bitmap = CGBitmapContextCreate(NULL, targetHeight, targetWidth, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo); 

    } 

    if (sourceImage.imageOrientation == UIImageOrientationLeft) { 
     CGContextRotateCTM (bitmap, M_PI_2); // + 90 degrees 
     CGContextTranslateCTM (bitmap, 0, -targetHeight); 

    } else if (sourceImage.imageOrientation == UIImageOrientationRight) { 
     CGContextRotateCTM (bitmap, -M_PI_2); // - 90 degrees 
     CGContextTranslateCTM (bitmap, -targetWidth, 0); 

    } else if (sourceImage.imageOrientation == UIImageOrientationUp) { 
     // NOTHING 
    } else if (sourceImage.imageOrientation == UIImageOrientationDown) { 
     CGContextTranslateCTM (bitmap, targetWidth, targetHeight); 
     CGContextRotateCTM (bitmap, -M_PI); // - 180 degrees 
    } 

    CGContextDrawImage(bitmap, CGRectMake(0, 0, targetWidth, targetHeight), imageRef); 
    CGImageRef ref = CGBitmapContextCreateImage(bitmap); 
    UIImage* newImage = [UIImage imageWithCGImage:ref]; 

    CGContextRelease(bitmap); 
    CGImageRelease(ref); 

    return newImage; 
} 

@end 
+0

我沒有選擇使用較小的圖像,如果你這樣做是一個更好的選擇順便說一句。 – 2013-02-22 02:47:56

+0

太棒了!很高興聽到別人也有這個問題!我很高興我不必現在就放棄我的應用程序!謝謝! – user2014741 2013-02-22 02:54:26

2

的最有效方式從磁盤加載的圖像的較小版本是這樣的:代替使用imageNamed:,使用Image我/ O框架請求縮略圖,該縮略圖即將顯示的實際尺寸,請致電CGImageSourceCreateThumbnailAtIndex。下面是從我的書的例子:

NSURL* url = 
    [[NSBundle mainBundle] URLForResource:@"colson" 
          withExtension:@"jpg"]; 
CGImageSourceRef src = 
    CGImageSourceCreateWithURL((__bridge CFURLRef)url, nil); 
CGFloat scale = [UIScreen mainScreen].scale; 
CGFloat w = self.iv.bounds.size.width*scale; 
NSDictionary* d = 
    @{(id)kCGImageSourceShouldAllowFloat: (id)kCFBooleanTrue, 
    (id)kCGImageSourceCreateThumbnailWithTransform: (id)kCFBooleanTrue, 
    (id)kCGImageSourceCreateThumbnailFromImageAlways: (id)kCFBooleanTrue, 
    (id)kCGImageSourceThumbnailMaxPixelSize: @((int)w)}; 
CGImageRef imref = 
    CGImageSourceCreateThumbnailAtIndex(src, 0, (__bridge CFDictionaryRef)d); 
UIImage* im = 
    [UIImage imageWithCGImage:imref scale:scale 
        orientation:UIImageOrientationUp]; 
self.iv.image = im; 
CFRelease(imref); CFRelease(src); 

這是一個巨大的浪費內存問一個UIImageView顯示比UIImageView的本身較大的圖像,作爲位圖的完整大小的圖片必須保持在內存中。 Image I/O框架生成較小的版本,甚至沒有將整個原始圖像作爲位圖解壓縮到內存中。