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