Вопрос

Я использую 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];

Кажется немного как черное магическое кодирование, но это работает.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top