UIImage imageNamed 上的实时应用程序崩溃:
Posted
技术标签:
【中文标题】UIImage imageNamed 上的实时应用程序崩溃:【英文标题】:Live app crash on UIImage imageNamed: 【发布时间】:2015-12-01 14:33:49 【问题描述】:我的应用程序出现了一些奇怪的问题,使用 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 我很确定这是没有必要的,即使不使用 images.xcassets。 @Kevin 确实,如果图像是 png 类型,则没有必要。如果是jpg,则必须指定扩展名。 @ejanowski 图片是作为单个矢量导入的 PDF。 我认为图像或内存压力也不是问题。对我来说,您似乎调用了一个已被释放(释放)的对象(观察者)。 CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION 【参考方案1】:我在内存不足的情况下使用 [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:
讨论
此方法将图像数据加载到内存中并将其标记为可清除。如果数据被清除并需要重新加载,则图像对象会从指定路径再次加载该数据。
【讨论】:
【参考方案2】:https://github.com/rickytan/RTImageAssets
将上述插件安装到 xcode 并转到文件 -> imageAssets ->Generate Missing assets.i 将生成所有丢失的图像。
【讨论】:
完美的插件来生成丢失的资产。谢谢@Janak LN 因为我使用 PDF 文件作为资产,所以没有丢失资产。每个图像有一个资产,并且在构建时,所有必需的图像大小都由图像资产创建。【参考方案3】:我在这里看到的唯一可能性是特定设备可能没有正确的文件。例如,如果设备具有 Retina 显示屏并且图像资源中没有 @2x 图像,则它将返回为 nil 等。
我的建议是确保所有需要的尺寸都实际存在于图片资源中 + 确保使用 asset group name 作为 imageNamed: 参数。
另外,您是否在各种模拟器或真实设备上对其进行测试?
【讨论】:
我已经在崩溃的设备上进行了测试。它并不总是崩溃。我什至无法在设备上重现它,它有时会崩溃。【参考方案4】:您可能在 iPhone 4/4s 上使用高分辨率图像和检查,反之亦然。 在图像资产中添加所有尺寸的图像,然后检查图像是否返回 nil。 不用@2x,@3x,如果我们使用图片资源,它会自动从图片资源中取合适的大小。
【讨论】:
我使用的是单个向量,所以没有@2x
或@3x
。它似乎也发生在 iPhone 6 上。
如果您单独使用图像,而不使用 image.xcassets 那么您可以直接从 @2x
或 @3x
存在 nog .png 文件且没有大小。以上是关于UIImage imageNamed 上的实时应用程序崩溃:的主要内容,如果未能解决你的问题,请参考以下文章
UIImage 的 -imageNamed: 方法是不是适用于存储在“文档”中的图像文件?
UIImage imageNamed 不使用 xcode 4.4 显示图像
UIImage imageNamed 在应用程序 A 中给出 nil,但在应用程序 B、C、D 中不给出
无法使用 imageNamed 方法获取 UIImage 对象