Представление NSViewController не выпускается при использовании в основанном на представлении NSTableView

У меня есть основанный на представлении 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];
}

Я попытался воспроизвести проблему с помощью небольшого образца кода, и у меня такая же проблема, представление контроллера представления освобождается только тогда, когда я не возвращаю непосредственно представление контроллера представления.

Кто-нибудь может мне помочь?


person Johnmph    schedule 23.02.2013    source источник


Ответы (2)


Обнаружено, 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;
}
person Johnmph    schedule 23.02.2013

Вы можете использовать:

[inspectorViewController.view removeFromSuperview]

перед удалением контроллера представления.

person Rakesh    schedule 23.02.2013
comment
Почему? Разве это не выполняется автоматически NSTableView removeRowsAtIndexes: withAnimation :? Когда я использую решение, которое работает (захват представления контроллера представления в другом представлении), все в порядке без необходимости вызова removeFromSuperview - person Johnmph; 23.02.2013
comment
Вероятно, это потому, что вы автоматически освобождаете родительский вид, и дочерний вид будет освобожден в процессе. Я не знаю, делает ли это «removeRowsAtIndexes: withAnimation»? Вы пробовали это? - person Rakesh; 23.02.2013
comment
tableView: viewForTableColumn: row: запрашивает автоматически выпущенное представление, поэтому во втором примере я автоматически выпустил родительский вид. Когда я возвращаю InspectorViewController.view, я не сохраняю его, поэтому он должен быть освобожден при освобождении контроллера представления (поскольку он сохраняет его) и при удалении представления из представления таблицы (выполняется с помощью removeRowsAtIndexes: withAnimation или reloadData). - person Johnmph; 23.02.2013
comment
Хорошо. А как вы проверяете, выпущен ли просмотр или нет? - person Rakesh; 23.02.2013
comment
Просто подкласс NSView с входом в систему Dealloc - person Johnmph; 23.02.2013
comment
Хм. Возможно, вы могли бы создать подкласс NSTableCellView только для проверки, вызывается ли освобождение для этого представления. В противном случае у меня сейчас нет идей. : | - person Rakesh; 23.02.2013
comment
Уже сделано, и NSTableCellView выпущен. Я проверил стек вызовов на предмет сохранения / освобождения представления в хорошем и плохом коде, и есть [NSTableRowView setView: atColumn:], который сохраняет представление в плохом коде, которого нет в хорошем коде. Может быть, это проблема, но она внутренняя для NSTableView - person Johnmph; 23.02.2013
comment
Обнаружено, что NSTableView сохраняет представление для повторного использования, поэтому я добавил [_inspectorViewController.view setIdentifier: nil]; и он выпущен. В любом случае спасибо за помощь - person Johnmph; 23.02.2013
comment
Прохладный. Спасибо за информацию. Я не понимаю, почему NSTableViewCell не используется повторно в той же ситуации. - person Rakesh; 23.02.2013
comment
Может быть, потому что представление контроллера представления имеет свой идентификатор, установленный контроллером представления, а новый NSView не имеет идентификатора? - person Johnmph; 23.02.2013