【问题标题】:How to ensure that UIImage is never released?如何确保 UIImage 永远不会被释放?
【发布时间】:2010-11-18 05:57:34
【问题描述】:

我从 iPhone 上抓取了崩溃日志:

Exception Type:  EXC_BAD_ACCESS (SIGBUS)
Exception Codes: KERN_PROTECTION_FAILURE at 0x0000000c
Crashed Thread:  0

Thread 0 Crashed:
0   libobjc.A.dylib                 0x30011940 objc_msgSend + 20
1   CoreFoundation                  0x30235f1e CFRelease + 98
2   UIKit                           0x308f4974 -[UIImage dealloc] + 36
3   CoreFoundation                  0x30236b72 -[NSObject release] + 28
4   UIKit                           0x30a00298 FlushNamedImage + 64
5   CoreFoundation                  0x30250a20 CFDictionaryApplyFunction + 124
6   UIKit                           0x30a0019c _UISharedImageFlushAll + 196
7   UIKit                           0x30a00730 +[UIImage(UIImageInternal) _flushCacheOnMemoryWarning:] + 8
8   Foundation                      0x3054dc7a _nsnote_callback + 178
9   CoreFoundation                  0x3024ea52 _CFXNotificationPostNotification + 298
10  Foundation                      0x3054b854 -[NSNotificationCenter postNotificationName:object:userInfo:] + 64
11  Foundation                      0x3054dbba -[NSNotificationCenter postNotificationName:object:] + 14
12  UIKit                           0x30a00708 -[UIApplication _performMemoryWarning] + 60
13  UIKit                           0x30a006a0 -[UIApplication _receivedMemoryNotification] + 128
14  UIKit                           0x30a005d0 _memoryStatusChanged + 56
15  CoreFoundation                  0x30217410 __CFNotificationCenterDarwinCallBack + 20
16  CoreFoundation                  0x3020d0aa __CFMachPortPerform + 72
17  CoreFoundation                  0x30254a70 CFRunLoopRunSpecific + 2296
18  CoreFoundation                  0x30254164 CFRunLoopRunInMode + 44
19  GraphicsServices                0x3204529c GSEventRunModal + 188
20  UIKit                           0x308f0374 -[UIApplication _run] + 552
21  UIKit                           0x308eea8c UIApplicationMain + 960
...
...

根据我之前的问题Can somebody give me a hand about this stacktrace in iPhone app?,我主要围绕 UIImage 部分更改了代码。我现在使用 [[UIImage alloc] initWithContentsOfFile ... ]。没有更多 [UIImage imageNamed: ... ] 或类似的东西。部分如下。

//this is a method of a subclass of UIImageView.
    - (void) reviewImage: (bool) review{
        NSString* st;
        if (review){
        NSString* origin = [NSString stringWithString: [[ReviewCardManager getInstance] getCardImageString:chosenIndex]];
        NSString* stt = [origin substringToIndex: [origin length]-4];

        st = [[NSString alloc] initWithString: stt];

        if (myImageFlipped == nil)
        myImageFlipped = [[UIImage alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForResource:st ofType:@"png"]];
        [self setImage:myImageFlipped];

        if (notRotated){
            self.transform = CGAffineTransformRotate(self.transform, [MyMath radf:rotate]);
            notRotated = false;
        }
    }else{
        st = [[NSString alloc] initWithFormat:@"sc%d", chosenNumber];

        if (myImage == nil)
        myImage = [[UIImage alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForResource:st ofType:@"png"]];

        [self setImage:myImage];

        if (notRotated){
            self.transform = CGAffineTransformRotate(self.transform, [MyMath radf:rotate]);
            notRotated = false;
        }

    }
    [st release];
}

我也已经在属性中保留了 UIImage。

@property (nonatomic, retain) UIImage* myImage, *myImageFlipped;

内存泄漏问题也得到了解决。这些变量在 dealloc 方法中释放。

我以为我已经成功杀死了这个错误,但似乎我仍然有一个罕见的错误问题。

根据崩溃日志,我的应用程序喊出了“performMemoryWarning”。我只是“分配”了 13 个 .png 图像,大小为 156 x 272。我很困惑。这些图像不应该占用太多内存,以至于超过了 iPhone 的 RAM。还是我忽略了什么?请指教。

【问题讨论】:

  • 您的属性似乎被称为“myImage”,但您的 setter 被称为“setImage:”。你能解释一下这里发生了什么吗?
  • 我是 UIImageView 的子类,这个类有 2 个 UIImage。当我想改变 UIImageView 的图像时,我基本上是调用 setImage。

标签: iphone memory-management uiimageview uiimage


【解决方案1】:

为了帮助您解决内存问题和 UIImages,您可能需要使用来自文档的 UIImage 的 imageNamed convience 方法:

This method looks in the system caches for an image object with the specified name and returns that object if it exists. If a matching image object is not already in the cache, this method loads the image data from the specified file, caches it, and then returns the resulting object.

或者,如果您在切换到 UIImage imageNamed 后仍然遇到内存问题,您可能需要转到 this route,因为使用方便方法存在一些缺点。

【讨论】:

  • 不,发帖人已经提到他们已将 imageNamed 移出 离开,我建议这样做以解决这些内存警告,因为 imageNamed 的缓存超出了程序员的控制。
  • 啊,我读过那部分。在这种情况下,链接博客文章中的自定义缓存会更有意义。
【解决方案2】:

问题解决了。我忘了在一处更改 UIImage。现在,所有 UIImage 都是真正的“分配”,不再是自动释放。

仅供参考,如果您使用的是 [UIImage imageNamed: ... ],请在 iPhone 模拟器上使用“模拟内存警告”来查看当真实设备内存不足时您是否遇到问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-06
    相关资源
    最近更新 更多