Получение URL-адреса от BeadshistModalforWindow:
-
24-09-2019 - |
Вопрос
Я использую OpenPanel, чтобы получить URL-адрес пути файла. Это работает:
[oPanel beginSheetModalForWindow:theWindow completionHandler:^(NSInteger returnCode)
{
NSURL *pathToFile = nil;
if (returnCode == NSOKButton)
pathToFile = [[oPanel URLs] objectAtIndex:0];
}];
Это не приведет к «присваиванию переменной только для чтения»:
NSURL *pathToFile = nil;
[oPanel beginSheetModalForWindow:theWindow completionHandler:^(NSInteger returnCode)
{
if (returnCode == NSOKButton)
pathToFile = [[oPanel URLs] objectAtIndex:0];
}];
return pathToFile;
В целом, любая попытка извлечения PathtoFile из контекста Опанеля не удалась. Это не такое большое дело для небольших ситуаций, но, поскольку мой код растет, я вынужден все настроить - разборы XML, основные данные и т. Д. - внутри неподходящего региона. Что я могу сделать, чтобы извлечь PathtoFile?
Спасибо.
Решение
Это не приведет к «присваиванию переменной только для чтения»:
NSURL *pathToFile = nil; [oPanel beginSheetModalForWindow:theWindow completionHandler:^(NSInteger returnCode) { if (returnCode == NSOKButton) pathToFile = [[oPanel URLs] objectAtIndex:0]; }]; return pathToFile;
Да, потому что вы пытаетесь назначить копию pathToFile
Переменная, которая производится при создании блока. Вы не назначаете на оригинал pathToFile
Переменная, которую вы объявили вне блока.
Вы могли бы использовать то __block
ключевое слово Чтобы допустить блок назначить эту переменную, но я не думаю, что это поможет, потому что beginSheetModalForWindow:completionHandler:
не блокирует. (Документация не упоминает об этом, но нет причин для блокировки метода, и вы можете проверить с помощью журнала, что это не так.) Сообщение немедленно возвращается, пока панель все еще работает.
Итак, вы пытаетесь установить свой блок заканчивания обработчика для локальной переменной, но ваш метод, в котором вы объявили локальную переменную, вероятно, вернутся к запуску временных блоков, поэтому он не сможет работать с ценность, что блок осталось оставит в переменной.
Что бы вы ни делали с pathToFile
должно быть либо в самом блоке, либо в способе (принимая NSURL *
аргумент), что блок может позвонить.
Другие советы
Вы также можете RunModal после того, как вы начнете лист, вам просто нужно убедиться, что вы заканчиваете лист позже. Таким образом, вам не нужно согнуть волю Apple, он не устарел, и он все еще должен работать идеально.
NSOpenPanel *openPanel = [NSOpenPanel openPanel];
[openPanel beginSheetModalForWindow:window completionHandler:nil];
NSInteger result = [openPanel runModal];
NSURL *url = nil;
if (result == NSFileHandlingPanelOKButton)
{
url = [openPanel URL];
}
[NSApp endSheet:openPanel];
Кажется немного как черное магическое кодирование, но это работает.