Я разрабатываю приложение Mac, которое запрашивает у пользователя файлы с использованием NSOpenPanel. Приложение изолировано (тестирование на OSX 10.9.4). Я заметил, что если я открываю большое количество файлов (~ 3000), открытая панель начинает испускать ошибки в журнале. Это также происходит, если я попытаюсь несколько раз открыть меньше файлов в патронах.
После того, как ошибки начнут появляться в первый раз, каждый раз, когда NSOpenPanel снова используется для открытия файлов, независимо от количества файлов, эти ошибки будут генерироваться снова (пока приложение не будет закрыто).
Сообщение об ошибке выглядит следующим образом:
TestPanel[98508:303] __41+[NSSavePanel _consumeSandboxExtensions:]_block_invoke: sandbox_consume_fs_extension failed
Одна строка для каждого файла, который я пытаюсь открыть.
Мне удалось воспроизвести это поведение с помощью простого приложения: изолированное приложение с одной кнопкой, вызывающее следующий код:
NSOpenPanel* panel = [NSOpenPanel openPanel];
[panel setAllowsMultipleSelection:YES];
[panel setCanChooseDirectories:NO];
[panel setCanChooseFiles:YES];
[panel beginSheetModalForWindow:[self window] completionHandler:^(NSInteger result) {
NSLog(@"%lu", [panel.URLs count]);
}];
Ошибки появляются до того, как код достигнет обработчика завершения.
Кажется, что я все еще могу получить URL-адреса с панели в обработчике завершения, но он действительно загрязняет системный журнал.
EDIT:
Кажется, что эта проблема напрямую не связана с панелями NSOpenPanel/NSSavePanel. Очень похожее происходит при использовании drap/drop с файлами. Что-то вроде этого:
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender {
...
NSPasteboard *pboard = [sender draggingPasteboard];
if ([[pboard types] containsObject:NSURLPboardType]) {
NSArray *urls = [pboard readObjectsForClasses:@[[NSURL class]] options:nil];
}
...
}
Это приведет к появлению следующих сообщений журнала при перетаскивании большого количества файлов ( "магический" номер кажется где-то около 2900):
Consume sandbox extension for itemIdentifier (2937) from pasteboard failed!
Как и в случае с NSOpenPanel, после первого появления этого, каждый удаленный файл генерирует ту же ошибку в журнале.
ИЗМЕНИТЬ 2:
@mahal tertin ответ указал мне в правильном направлении. Проблема в том, что количество файлов и тот факт, что ресурсы ресурсов с ограниченным доступом ограничены.
Однако, похоже, не найдено разумного решения. Проблема заключается в том, что когда пользователь нажимает "ОК" на NSOpenPanel (или удаляет файлы с помощью элемента управления перетаскиванием), за кулисами ОС уже пытается создать эти URL-адреса с защитой и неявно вызывает startAccessingSecurityScopedResource
для вас. Поэтому, если пользователь пытается открыть больше файлов, чем предел, ресурсы исчерпаны, и единственным вариантом является закрытие и перезапуск приложения.
Вызов stopAccessingSecurityScopedResource
по возвращенным URL-адресам, похоже, освобождает ресурсы, однако это решение было обескуражено представителем Apple на официальном форуме разработчиков (ссылка находится за логином).
Похоже, что приложение находится на милости пользователя, чтобы не открывать слишком много файлов. И это даже не сразу, поскольку нет утвержденного способа выпуска этих ресурсов. Вы можете предупредить пользователя в документации или даже с предупреждением в приложении, но нет способа предотвратить их испортить приложение и принудительно перезапустить.
Итак, если приложение работает достаточно долго, и пользователь продолжает открывать файлы, приложение со временем станет непригодным.
Ищем разумное решение для этого.