Авария в реальном времени на 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, если мы используем объекты изображения, он автоматически примет соответствующий размер из объектов изображения.