Странная проблема с UIDocumentInteractionController

Я не знаю то, что неправильно с этим кодом, но каждый раз когда я запускаю приложение, после того, как Меню показывают, сбой приложения.

NSString * path = [[NSBundle mainBundle] pathForResource:@"tung" ofType:@"doc"];

UIDocumentInteractionController *docController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:path]];

docController.delegate = self;

//[docController presentPreviewAnimated:YES];

CGRect rect = CGRectMake(0, 0, 300, 300);
[docController presentOptionsMenuFromRect:rect inView:self.view animated:YES];

Ошибка я добрался:

*** Завершение приложения из-за неперехваченного исключения 'NSGenericException', причина: '-[UIPopoverController dealloc], достигнутый, в то время как легкая сдоба все еще видима.'

Что я должен сделать теперь?

15
задан Atulkumar V. Jain 15 October 2012 в 11:37
поделиться

2 ответа

Чтобы предварительно просмотреть документ с помощью одноразового UIDocumentInteractionController, вы должны сохранить его после взаимодействияControllerWithURL и автоматически выпустить его в методе UIDocumentInteractionControllerDelegate documentInteractionControllerDidDismissOptionsMenu. Как заметил Дэвид Лю, при его выпуске произойдет сбой. Но автоспуск работает. Я проверил, что действительно вызывается dealloc.

Следующий код должен работать:


- (void)previewDocumentWithURL:(NSURL*)url
{
    UIDocumentInteractionController* preview = [UIDocumentInteractionController interactionControllerWithURL:url];
    preview.delegate = self;
    [preview presentPreviewAnimated:YES];
    [preview retain];
}
- (void)documentInteractionControllerDidEndPreview:(UIDocumentInteractionController *)controller
{
    [controller autorelease];
}
23
ответ дан 1 December 2019 в 01:38
поделиться

Это в основном старая проблема управления памятью.

[UIDocumentInteractionController InteractionControllerWithURL: [NSURL fileURLWithPath: path]] возвращает автоматически выпущенный объект, поэтому он будет автоматически выпущен вскоре после завершения блока кода. Я предполагаю, что это не похоже на presentModalViewController , который сохранит копию для вас, но это побочный момент.

По сути, вам нужно сохранить его до того, как закончится ваш блок кода. Более раздражающая часть - это отслеживание того, что делает docController, чтобы не допустить утечки памяти. Вам нужно будет проверить результат
[docController presentOptionsMenuFromRect: rect inView: self.view animated: YES];

Если он возвращает NO, это означает, что меню никогда не появлялось, и поэтому вы должны немедленно выпустить его (если вы уже сделали сохранить).

Однако, если он возвращает YES, вам необходимо реализовать методы делегата для docController и освободить его при закрытии меню (в данном случае это будет, когда:
- (void) documentInteractionControllerDidDismissOptionsMenu: (UIDocumentInteractionController *) вызывается контроллер
.

РЕДАКТИРОВАТЬ: Я хочу внести здесь исправление:

Предыдущий ответ приведет к сбою, если закрыть всплывающее меню. По сути, действительно нет никакого хорошего способа создать одноразовый DocController. Вместо этого я думаю, что лучше просто создать по одному для каждого файла, который вам нужен в контроллере просмотра, и освободить его, когда вы полностью закончите. В противном случае вы столкнетесь с множеством возможных случаев, когда DocController будет выпущен слишком рано и выйдет из строя.

8
ответ дан 1 December 2019 в 01:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: