iOS UI 外观错误

Posted

技术标签:

【中文标题】iOS UI 外观错误【英文标题】:iOS UIAppearance Error 【发布时间】:2012-06-21 03:28:40 【问题描述】:

我正在构建一个文件管理应用程序,在调用UIImagePickerControllerMPMediaPickerController 时偶尔会收到以下错误:

*** -[_UIImageViewPretiledImageCacheKey hash]: message sent to deallocated instance 0x140dc0

我最近使用 ios 5 的 UIAppearance API 为我的应用程序提供了一个自定义主题,这就是我开始收到此错误的时候。通过猜测和检查,我发现了导致此错误的代码有问题的行:

UIImage *backButtonImage = [[UIImage imageNamed:@"backButton.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(12, 16, 12, 8)];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
UIImage *barButtonImage = [[UIImage imageNamed:@"barButton.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(14, 12, 14, 12)];
[[UIBarButtonItem appearance] setBackgroundImage:barButtonImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

我不知道这段代码是如何触发上述错误的。能否请您向我解释此错误的来源并提供解决方案。

提前感谢您的帮助, 古维

【问题讨论】:

对于那些不幸看到这个崩溃的人,这里是另一个非常有用的资源:@​​987654321@ 我们知道为什么会发生这种情况吗?我在 iOS 6 中得到了同样的结果。我正在自定义绘制自己的 20x20 图像,并且在所有方面都有 9 的上限插图... @bogardon 您是否在非视网膜设备上遇到此崩溃? 【参考方案1】:

经过一些更彻底的测试,我得出的结论是这个问题仅限于视网膜设备。问题出在@2x 图像中。它们的分辨率为奇数(例如 59 像素 x 60 像素)。我所做的只是重新创建图像并将分辨率更改为 60 x 60 像素,我再也没有遇到过这个问题。

我对这个解决方案有点惊讶,因为我发现错误消息和代码行之间没有关联,但最终,是图像导致了这个问题。

【讨论】:

我的@2x 图像没有奇数分辨率,但偶尔仍会发生这种崩溃...【参考方案2】:

我有一个similar problem,但我的崩溃是由UIImageView 中可调整大小的图像引起的。

我的可调整大小的图像具有顶部 = 30 像素、左侧 = 20 像素、底部 = 1 像素、右侧 = 10 像素的边缘插图。图像为 43x45,因此其可调整大小的区域为 13x14。我使用的是 iOS6,因此我能够通过将 UIImageResizingModeStretch 指定为 resizingMode 来解决此问题,以用于 -[UIImage resizableImageWithCapInsets:resizingMode:]

作品:

UIImage *image = [UIImage imageNamed:name];
UIImage *resizableImage = [image resizableImageWithCapInsets:edgeInsets resizingMode:UIImageResizingModeStretch];

EXC_BAD_ACCESS[_UIImageViewPretiledImageCacheKey hash]: message sent to deallocated instance 0xb14deb0NSZombieEnabled 崩溃:

UIImage *image = [UIImage imageNamed:name];
UIImage *resizableImage = [image resizableImageWithCapInsets:edgeInsets];

【讨论】:

【参考方案3】:

下面的代码我得到了同样的结果

UIImage* image = [UIImage stretchableImageNamed:@"imageName"];
self.backgroundView = [[UIImageView alloc] initWithImage:image];
self.selectedBackgroundView = [[UIImageView alloc] initWithImage:image];

其中selfUITableViewCellstretchableImageNamed: 很简单

+(UIImage*)stretchableImageNamed:(NSString*)name

    UIImage *img = [UIImage imageNamed:name];
    CGSize sz = img.size;
    int left = (sz.width - 1.) / 2.;
    int top = (sz.height - 1.) / 2.;
    return [img resizableImageWithCapInsets:UIEdgeInsetsMake(top, left, top, left)];

这有帮助:

self.backgroundView = [[UIImageView alloc] initWithImage:[UIImage stretchableImageNamed:@"imageName"]];
self.selectedBackgroundView = [[UIImageView alloc] initWithImage:[UIImage stretchableImageNamed:@"imageName"]];

【讨论】:

以上是关于iOS UI 外观错误的主要内容,如果未能解决你的问题,请参考以下文章

IOS UI外观

iOS 使用UI控件的外观协议UIAppearance进行设置默认UI控件样式

iOS6 vs iOS7 外观界面生成器

调整窗口大小时,SwiftUI TextField 文本边界无法使用 GeometryReader 更新,导致外观错误

UIAppearance setTranslucent 错误:非法属性类型,c 为外观设置器,_installAppearanceSwizzleForSetter

什么决定了 iOS 应用程序是不是会在 iOS 7 中获得新外观