【问题标题】:NSViewController view's not released when used in a view based NSTableView在基于视图的 NSTableView 中使用时,NSViewController 视图未发布
【发布时间】:2013-02-23 17:08:47
【问题描述】:

我有一个基于视图的 NSTableView,它使用 NSViewController 子类 (InspectorViewController) 的视图:

- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
    // Get inspector view controller
    InspectorViewController *inspectorViewController = [_inspectorViewControllers objectAtIndex:row];

    // Return its view
    return inspectorViewController.view;
}

除了 NSViewController 的视图在我移除视图控制器(释放良好)时永远不会释放之外,一切都很好。

如果我改用此代码:

- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
    // Get inspector view controller
    InspectorViewController *inspectorViewController = [_inspectorViewControllers objectAtIndex:row];

    // Return its view
    NSTableCellView *view = [[NSTableCellView alloc] init] autorelease];
    [view addSubview:inspectorViewController.view];
    return view;
}

当我移除视图控制器时视图被正确释放。 这是删除视图控制器的代码:

- (void)inspectorViewControllerClosed:(InspectorViewController *)inspectorViewController {
    // Get index of inspector view controller
    NSUInteger index = [_inspectorViewControllers indexOfObject:inspectorViewController];

    // Remove inspector view controller in array
    [_inspectorViewControllers removeObject:inspectorViewController];

    // Create index set
    NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:index];

    // Begin updates
    [_tableView beginUpdates];

    // Move row in table view
    [_tableView removeRowsAtIndexes:indexSet withAnimation:NSTableViewAnimationEffectFade];

    // End updates
    [_tableView endUpdates];
}

我尝试用一​​个小示例代码重现问题,我也遇到了同样的问题,只有当我不直接返回视图控制器的视图时,视图控制器的视图才会被释放。

有人可以帮帮我吗?

【问题讨论】:

    标签: macos cocoa memory-leaks nstableview nsviewcontroller


    【解决方案1】:

    发现,NSTableView 保留视图以供重用,使用此代码正确释放:

    - (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
        // Get inspector view controller
        InspectorViewController *inspectorViewController = [_inspectorViewControllers objectAtIndex:row];
    
        // Disable reusing ?
        [_inspectorViewController.view setIdentifier:nil];
    
        // Return its view
        return inspectorViewController.view;
    }
    

    【讨论】:

      【解决方案2】:

      你可以使用:

      [inspectorViewController.view removeFromSuperview]
      

      在移除视图控制器之前。

      【讨论】:

      • 为什么?这不是由 NSTableView removeRowsAtIndexes:withAnimation: 自动完成的吗?当我使用有效的解决方案时(在另一个视图中加入视图控制器的视图),一切都可以,无需调用 removeFromSuperview
      • 这可能是因为您正在自动释放父视图,而子视图将在此过程中释放。我不知道'removeRowsAtIndexes:withAnimation'是否这样做?你试过了吗?
      • tableView:viewForTableColumn:row: 要求自动释放视图,这就是我在第二个示例中自动释放父视图的原因。当我返回inspectorViewController.view 时,我不保留它,所以它必须在视图控制器被释放(因为它保留它)和视图从表视图中移除时(由removeRowsAtIndexes:withAnimation 或reloadData 完成)被释放。跨度>
      • 好的。你如何检查视图是否被释放?
      • 只是 NSView 的一个子类,登录 dealloc
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多