Приложение My Mac копирует файлы, которые перетаскивает пользователь. Приложение изолировано. Теперь у меня есть ошибка, которую я могу надежно воспроизвести в Xcode, но я не могу отследить источник.
Когда я добавляю определенное количество файлов, приложение внезапно перестает получать доступ к более поздним. Все исходные файлы находятся на один уровень ниже из одного и того же родительского каталога, и все папки между ними имеют одинаковые разрешения, проверенные с помощью ls -l
. Приложение сохраняет закладку уровня приложения для Destination Directory
, доступ к которой осуществляется перед созданием .directoryName
и началом копирования файла.
Я получаю сообщение об ошибке:
Error Domain = NSCocoaErrorDomain Code = 513 ""Filename.ext" не может быть скопирован, так как у вас нет разрешения на доступ к ".directoryName"." UserInfo=0x6080000eaf80 {NSSourceFilePathErrorKey=/Users/Имя пользователя/Родительский каталог/Subdir/Filename.ext, NSUserStringVariant=(Copy), NSDestinationFilePath=/Users/Username/Desktop/Destination Directory/.directoryName/Filename.ext, NSFilePath=/Users/ Имя пользователя/Родительский каталог/Подкаталог/Имя файла.ext, NSUnderlyingError=0x6080004567a0 «Операция не может быть завершена. Операция не разрешена»}
Я сделал следующее во время отладки:
- Попытался добавить
Subdir/Filename.ext
самостоятельно после выхода и перезапуска, что сработало. - Проверено (с помощью
lsof
и Activity Monitor), что у меня нет утечки файловых дескрипторов (что, как я знаю, вызывало у меня аналогичные проблемы в прошлом) - Проверено символическими точками останова, что каждый вызов
-[NSURL startAccessingSecurityScopedResource]
to уравновешивается вызовом-[NSURL stopAccessingSecurityScopedResource]
(и их эквивалентамиCF
) - Определено, что
Filename.ext
и другие сбойные файлы успешно добавляются без остальных. - То же самое происходит для сборок Debug и Release в отладчике и вне его.
- Я пытался запустить как root, но мое приложение так не запускается. При запуске в отладчике я получаю исключение
EXC_BAD_INSTRUCTION
, а запуск его сsudo
в командной строке вызывает сбой (вероятно, тот же самый)
Похоже, такое поведение указывает на какую-то утечку ресурсов, но мне пока не удалось это обнаружить. Любые идеи, что еще может быть причиной этого?
Обновить
Я не готов объявить ответ, но я начал получать эти ошибки разрешения в другой части моего кода после того, как пользователь поместил файлы в приложение. Я заметил, что немного выше в журналах я видел сообщения, подобные следующим:
Не удалось использовать расширение песочницы для itemIdentifier (1) из картона!
Отслеживание этой ошибки привело меня к вопросу, который задал кто-то другой: Изолированное приложение для Mac исчерпывает ресурсы URL-адресов в области безопасности
К сожалению, в принятом ответе говорится (перефразируя) "жесткие ноги". Похоже, что Cocoa и сам механизм песочницы пропускают токены области безопасности (хотя я не могу проверить с помощью символических точек останова и не знаю другого способа проверить). После определенного (неизвестного) количества файловых операций с изолированными файлами вы начнете получать эту ошибку, и единственное решение — выйти и перезапустить.
Я хотел бы, чтобы был хотя бы какой-то способ предложить пользователю перезапустить, когда он приблизится, но я не уверен, как можно измерить, сколько из этих дескрипторов используется. Или, что еще лучше, если бы я мог вручную выполнить очистку после того, как закончу работу с отброшенными файлами, но я не уверен, как это будет работать, поскольку мне нужно использовать тип монтажного стола NSFilenamesPboardType
для получения путей к нескольким файлам. Я попытался создать из них NSURL
и остановить доступ к области безопасности, но это не дало никакого эффекта.
Обновление 2
Я отправил тикет DTS для этого, так как это влияет на пользователей и нет четкого обходного пути. Я обновлю вопрос (и, возможно, дам ответ?), Как только узнаю больше.
Ответ команды Apple DTS
Судя по всему, это известная проблема, решения которой нет. Я отправил радар: rdar://20652066, если хотите обмануть Это.