NSOpenPanel和检测到泄露的观察者

时间:2016-01-21 08:05:22

标签: objective-c cocoa 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 个答案:

答案 0 :(得分:0)

我可以使用以下技巧解决问题:

我在视图控制器中声明了一个变量:

__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];
}

没有警告!