UIImage imageNamed导致实时应用程序崩溃

17

我们的应用出现一些奇怪的问题,使用 UIImage 时会导致崩溃。我从图像资源中使用 [UIImage imageNamed:@"imageName"] 获取图像。但在某些设备上它会返回nil,这会导致我的应用程序崩溃,但它不应该是nil。我已经检查了它,并且它正在主线程上运行,剩余足够的内存(尽管内存严重不足)。

图像是作为单个矢量图像的PDF文件存在于图像资源中,这应该创建正确大小的图像。

有人可以给我指点如何解决这个问题吗?

Thread : Crashed: com.apple.main-thread
0  CoreFoundation                 0x1844d7108 CFDataGetBytePtr + 36
1  Foundation                     0x18545a848 bytesInEncoding + 204
2  CoreFoundation                 0x1844e88d4 -[__NSCFString UTF8String] + 80
3  CoreUI                         0x18d6827c0 -[CUIStructuredThemeStore _canGetRenditionWithKey:isFPO:lookForSubstitutions:] + 780
4  CoreUI                         0x18d6a5614 -[CUICatalog _resolvedRenditionKeyFromThemeRef:withBaseKey:scaleFactor:deviceIdiom:deviceSubtype:sizeClassHorizontal:sizeClassVertical:memoryClass:graphicsClass:graphicsFallBackOrder:] + 1484
5  CoreUI                         0x18d6a4784 -[CUICatalog namedLookupWithName:scaleFactor:deviceIdiom:deviceSubtype:sizeClassHorizontal:sizeClassVertical:] + 148
6  UIKit                          0x18a3df338 __98-[_UIAssetManager imageNamed:scale:idiom:subtype:cachingOptions:sizeClassPair:attachCatalogImage:]_block_invoke + 424
7  UIKit                          0x18a3df0d8 -[_UIAssetManager imageNamed:scale:idiom:subtype:cachingOptions:sizeClassPair:attachCatalogImage:] + 212
8  UIKit                          0x18a4f1698 -[UIImageAsset imageWithTraitCollection:] + 404
9  UIKit                          0x18a3df7c0 -[_UIAssetManager imageNamed:withTrait:] + 276
10 UIKit                          0x189e7277c +[UIImage imageNamed:inBundle:compatibleWithTraitCollection:] + 220
11 UIKit                          0x189ccb47c +[UIImage imageNamed:] + 124
12 Speakap                        0x1000bef50 -[LoadingView commonInit] (LoadingView.m:74)
13 Speakap                        0x1000beabc -[LoadingView initWithFrame:] (LoadingView.m:28)
14 Speakap                        0x1001348dc -[BaseTableViewController viewDidLoad] (BaseTableViewController.m:32)
15 Speakap                        0x1001570d4 -[BaseMessageViewController viewDidLoad] (BaseMessageViewController.m:66)
16 Speakap                        0x10014aa34 -[MessageViewController viewDidLoad] (MessageViewController.m:37)
17 UIKit                          0x189b8c098 -[UIViewController loadViewIfRequired] + 996
18 UIKit                          0x189ba4350 -[UIViewController __viewWillAppear:] + 132
19 UIKit                          0x189d3dfb4 -[UINavigationController _startCustomTransition:] + 1052
20 UIKit                          0x189c4a190 -[UINavigationController _startDeferredTransitionIfNeeded:] + 688
21 UIKit                          0x189c49e6c -[UINavigationController __viewWillLayoutSubviews] + 60
22 UIKit                          0x189c49dd4 -[UILayoutContainerView layoutSubviews] + 208
23 UIKit                          0x189b877ac -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 644
24 QuartzCore                     0x189386b58 -[CALayer layoutSublayers] + 148
25 QuartzCore                     0x189381764 CA::Layer::layout_if_needed(CA::Transaction*) + 292
26 QuartzCore                     0x189381624 CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 32
27 QuartzCore                     0x189380cc0 CA::Context::commit_transaction(CA::Transaction*) + 252
28 QuartzCore                     0x189380a08 CA::Transaction::commit() + 512
29 UIKit                          0x189b7d9d8 _afterCACommitHandler + 180
30 CoreFoundation                 0x1845afbd0 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32
31 CoreFoundation                 0x1845ad974 __CFRunLoopDoObservers + 372
32 CoreFoundation                 0x1845adda4 __CFRunLoopRun + 928
33 CoreFoundation                 0x1844dcca0 CFRunLoopRunSpecific + 384
34 GraphicsServices               0x18f718088 GSEventRunModal + 180
35 UIKit                          0x189bf4ffc UIApplicationMain + 204
36 Speakap                        0x100162b24 main (main.m:14)
37 libdyld.dylib                  0x19990a8b8 start + 4

你尝试过添加图像的扩展名吗?例如“imageName.png”?没有@2x/@3x。 - ejanowski
4
我很确定即使不使用images.xcassets,也从未需要这样做。 - Kevin
2
@Kevin确实,如果图像是png类型,则不需要IF语句。如果它是jpg,则必须指定扩展名。 - ejanowski
你是如何从单个向量创建图像并在应用程序中使用它们的? - Fahim Parkar
1
我认为问题不在于图像或内存压力。对我来说,似乎你调用了一个已被释放的对象(观察者)。CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION - ares777
显示剩余11条评论
4个回答

3
在低内存环境下使用[UIImage imageNamed:@""]可能会导致内存管理方面的一些"问题"。根据文档https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIImage_Class/index.html#//apple_ref/occ/clm/UIImage/imageNamed所述,该方法在系统缓存中查找指定名称的图像对象,并返回该对象(如果存在)。如果缓存中没有匹配的图像对象,则此方法会查找并从磁盘或资源目录加载图像数据,然后返回结果对象。在iOS 9及更高版本中,此方法是线程安全的。我不知道崩溃发生在哪个操作系统上,但这可能是一个想法。另外,如果您将imageNamed:替换为imageWithContentOfFile:initWithContentOfFile:,是否仍然会出现这种情况?内存管理是不同的(没有系统缓存),请参见https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIImage_Class/index.html#//apple_ref/occ/instm/UIImage/initWithContentsOfFile。该方法将图像数据加载到内存中并标记为可清除。如果数据被清除并需要重新加载,则图像对象会再次从指定路径加载该数据。

1

2
完美的插件来生成丢失的资源。谢谢你 @Janak LN。 - user3622576
2
由于我正在使用PDF文件作为资产,因此没有缺少的资产。每个图像都有一个资产,并且在构建时,所有所需的图像尺寸都由图像资产创建。 - rckoenes

0

我能看到的唯一可能性是,特定设备可能没有正确的文件。例如,如果设备具有Retina显示屏,并且图像资源中没有@2x图像,则会返回nil等。

我的建议是确保所有所需大小实际存在于图像资源中,并确保在imageNamed:参数中使用资产组名称

此外,您是否在各种模拟器或实际设备上进行测试?


1
我已经在出现崩溃的设备上进行了测试,但它并不总是会崩溃。即使在设备上我也无法复制该问题,因为它只是偶尔发生崩溃。 - rckoenes

0
可能你正在使用高分辨率图片并在 iPhone 4 / 4s 上检查,或反之亦然。 将所有图像资源的尺寸添加到图像资产中,然后检查图像是否返回 nil。 如果我们使用图像资产,则不需要提及 @2x,@3x,它会自动从图像资产中取适当的大小。

我正在使用单个向量,因此没有@2x@3x。而且似乎在iPhone 6上也会发生这种情况。 - rckoenes
如果您单独使用图像,而不是使用image.xcassets,则可以直接从<imageName.png>访问图像。 - Hemali Luhar
我知道这个,但我确定资产目录中有矢量图像!因此没有.png文件,也没有带有“@2x”或“@3x”的尺寸。 - rckoenes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接