Авария в реальном времени на UIImage imageNamed:

У меня возникают некоторые странные проблемы с нашим приложением, он сбой при использовании 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

Ответы

Ответ 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 будет генерировать все отсутствующие изображения.

введите описание изображения здесь

Ответ 3

Единственная возможность, которую я вижу здесь, заключается в том, что у конкретного устройства может отсутствовать соответствующий файл. Например, если устройство имеет дисплей Retina, и в объекте изображения нет изображения 2x2, то оно будет возвращено как ноль и т.д.

Мое предложение состоит в том, чтобы убедиться, что все необходимые размеры на самом деле существуют внутри объекта изображения + обязательно используйте имя группы активов для параметра imageNamed:

Кроме того, вы тестируете его на разных тренажерах или реальных устройствах?

Ответ 4

Возможно, вы используете изображение с высоким разрешением и проверяете iPhone 4/4 или vise-a-versa. Добавьте все размеры изображений в изображениях, а затем проверьте изображение, независимо от того, возвращается ли оно или нет. Не нужно упоминать @2x, @3x, если мы используем объекты изображения, он автоматически примет соответствующий размер из объектов изображения.