UIWebView сбой во втором запросе на загрузку PDF

У меня есть UIWebView, который я использую, чтобы показать несколько небольших PDF файлов. Пользователь выбирает статью новостей из таблицы, а затем статья (PDF) загружается в UIWebView на том же экране. Первая загрузка всегда идет отлично. Затем следующий элемент, который я выбираю (независимо от того, какой из них), сбрасывает приложение.

Вот как я загружаю каждую статью:

NSString *filePath = [[NSBundle mainBundle] pathForResource:articleFileName ofType:@"pdf"];
[articleView stopLoading];
[articleView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:filePath]]];

Сбой происходит после строки loadRequest.
При сбое информация об ошибке отсутствует. Кроме:

Все исключения {} 0x3629f000

Catchpoint 3 (исключение выбрано). (gdb)

Он просто падает до main(). Я проверил в отладчике, что он использует правильный путь к каждому запросу.

У меня работает NSZombies, и у меня есть точки останова для всех исключений.

Ответы

Ответ 1

У меня тоже есть эта проблема. Большое спасибо Стиву за то, что он помог мне сузить его еще дальше, мое исключение - это то же самое, что и его.

У вас есть разрыв во всех выбранных исключениях? Я обнаружил, что если я отключу эту точку останова, она больше не падает. Что заставило меня подумать, что это была просто ошибка в новой версии отладчика или iOS? Другая вещь, которая заставила меня думать, что это крушение не происходит, когда я запускаю устройство с iOS 4.3.x или 4.3 симулятором.

Ответ 2

Я вижу нечто похожее - и при освобождении веб-обозревателя после загрузки PDF файла, либо при загрузке html после загрузки PDF файла. Кажется, это rdar://10431759 (см. http://openradar.appspot.com/10431759). У меня нет возможности обойти это. Я могу воспроизвести его, загрузив pdf файл, а затем загрузив строку html @"<div></div>", поэтому она не является проблемой делегирования.

Если вы наберете "bt" в консоли gdb, вы можете получить реальную стекю, включая:

#0  0x37ccd1c8 in objc_exception_throw ()
#1  0x381817b8 in +[NSException raise:format:arguments:] ()
#2  0x381817b8 in +[NSException raise:format:arguments:] ()
#3  0x381817da in +[NSException raise:format:] ()
#4  0x35462628 in -[NSObject(NSKeyValueObserverRegistration) _removeObserver:forProperty:] ()
#5  0x35462296 in -[NSObject(NSKeyValueObserverRegistration) removeObserver:forKeyPath:] ()
#6  0x31fc3448 in -[UIWebPDFView _removeBackgroundImageObserverIfNeeded:] ()
#7  0x31fc36a8 in -[UIWebPDFView dealloc] ()
#8  0x37cc90c4 in _objc_rootRelease ()
#9  0x31dd2614 in -[UIWebPDFViewHandler clearAllViews] ()
#10 0x31d76708 in -[UIWebPDFViewHandler _replacePDFViewIfPresentWithWebDocView:] ()
#11 0x31d766a6 in -[UIWebPDFViewHandler _removePDFViewIfWebDocViewIsNotPDF:] ()
#12 0x31d76644 in -[UIWebBrowserView webView:didFirstVisuallyNonEmptyLayoutInFrame:] ()

При отладке устройства вы можете ввести "frame 0" и "po $r0", чтобы увидеть сообщение об исключении: (я думаю, что это "po $eax" в симуляторе.)

(gdb) frame 0
#0  0x37ccd1c8 in objc_exception_throw ()
(gdb) po $r0
Cannot remove an observer <UIWebPDFView 0x4a3200> for the key path "backgroundImage" from <UIPDFPageView 0x4a4bf0> because it is not registered as an observer.

Изменить: Эта проблема возникает, только когда у меня включен "Break on throw" для исключений Objective-C.

Ответ 3

У меня была аналогичная проблема, с моей подвеской UIWebView (просто замерзая на сером экране с вращающимся "нагрузочным" кругом, который так и не закончился). Если я выйду из программы, это приведет к сбою во втором загрузке.

Наконец, я сделал достаточно трассировки в нем и крутился вокруг, что я обнаружил, что если я сначала загрузил шрифт метки (с помощью CCLabelTTF с помощью Cocos2d) из пакета ресурсов приложения, THEN попытался загрузить PDF файл, то он будет работать и не будет терпеть крах.

Это очень уродливый взлом, но кто-то может найти его полезным.

// HACK: Loading a TTF font first is needed to properly load PDF / HTML
CCLabelTTF* label = [CCLabelTTF labelWithString:@"Testing" fontName:@"DIN-Black" fontSize:12];
[label setVisible:false];

// We never actually use the label -- we just create it so that it loads the font
NSString *path = [[NSBundle mainBundle]
                  pathForResource:myPDF
                  ofType:@"pdf"];

CCLOG(@"Retrieving PDF from '%@'", path);

NSURL *pdfUrl = [NSURL fileURLWithPath:path];
NSURLRequest *request = [NSURLRequest requestWithURL:pdfUrl];

[webView loadRequest:request];
[webView setScalesPageToFit:YES];
[super onEnter];