NSOpenPanel и обнаруженная утечка наблюдателя
Я получил предупреждение от XCode во время выполнения моей программы:
2016-01-21 03:19:26.468 IsoMetadonnees[1975:303] An instance 0x1004eefd0 of class NSVBOpenPanel was deallocated while key value observers were still registered with it. Observation info was leaked, and may even become mistakenly attached to some other object. Set a breakpoint on NSKVODeallocateBreak to stop here in the debugger. Here's the current observation info:
<NSKeyValueObservationInfo 0x608000444710> (
<NSKeyValueObservance 0x6080000d5310: Observer: 0x100592cf0, Key path: level, Options: <New: YES, Old: NO, Prior: NO> Context: 0x0, Property: 0x6080004486a0>
)
Проблема возникает, когда приложение представляет NSOpenPanel для выбора некоторых файлов, которые будут загружены асинхронно. Приложение не вылетает и файл корректно загружается...
Я не создаю никакого наблюдателя значения, поэтому я представляю, что наблюдатель создан NSOpenPanel, но я не знаю какой-либо процедуры для удаления наблюдателя, которого я не создал...
Несмотря на это предупреждение, я произвел несколько загрузок без какого-либо сбоя. Я использую свое приложение уже много лет без проблем, но недавно перешел на ARC; может быть проблема появилась (или обнаружена) в это время.
Вот упрощенная версия моего кода:
- (IBAction)ajoutFichier:(id)sender {
NSOpenPanel *openPanel = [NSOpenPanel openPanel];
// Here some configurations of openPanel
if ([openPanel runModal] == NSOKButton) {
tmp_listeURLFichiers = [openPanel URLs];
}
//[openPanel close]; // I add this code unsuccessfully
openPanel = nil; // I add this code unsuccessfully
// I call a task in back ground to load my files
if ((tmp_listeURLFichiers != nil) && ([tmp_listeURLFichiers count]>0))
[self performSelectorInBackground:@selector(ajouteListeFichiers:) withObject:tmp_listeURLFichiers];
}
// Load files in background
-(BOOL) ajouteListeFichiers:(NSArray *)listeDesFichierAAjouter {
@autoreleasepool {
// Some stuff to show a progress bar
// Loop to load selected files
for (id tmpCheminVersMonImage in listeDesFichierAAjouter) {
// Load files
}
} // <========== THE WARNING OCCURS AT THIS POINT, WHEN autoreleasepool is cleaned
return (YES);
}
Я пытаюсь добавить
[openPanel close];
а также
openPanel = nil;
заставить выпустить openPanel из памяти (и, следовательно, наблюдателей) перед запуском фоновой задачи, но это ничего не меняет...
Есть ли у вас какие-либо идеи?
Спасибо за помощь!
1 ответ
Я мог бы решить проблему, используя следующий прием:
Я объявляю переменную в моем контроллере представления:
__strong NSOpenPanel *prgOpenPanel;
Тогда я использую это в своем коде
//NSOpenPanel *prgOpenPanel = [NSOpenPanel openPanel];
self.prgOpenPanel = nil;
self.prgOpenPanel = [NSOpenPanel openPanel];
// Here some configurations of openPanel
if ([prgOpenPanel runModal] == NSOKButton) {
tmp_listeURLFichiers = [prgOpenPanel URLs];
if ((tmp_listeURLFichiers != nil) && ([tmp_listeURLFichiers count]>0))
[self performSelectorInBackground:@selector(ajouteListeFichiers:) withObject:tmp_listeURLFichiers];
}
Нет больше предупреждений!