Лучший способ управлять временем жизни экземпляра, созданного в методе класса - PullRequest
1 голос
/ 22 июля 2011

В приложении для домашних животных, которое я пишу, в главном окне у меня есть несколько пользовательских видов, выровненных друг под другом, каждый из которых имеет метку, поле со списком и кнопку.

Нажатие на кнопку вызывает код, который находит комбинированный список в том же представлении, а затем вызывает следующую функцию (метод класса RVListEditorController):

+ (void) editComboBox: (NSComboBox *) aComboBox
{
    // Analyze says "possible leak", but both methods ending the panel will release the controller.

    RVListEditorController *controller = [[RVListEditorController alloc] initWithComboBox: aComboBox];

    [NSApp beginSheet: [controller window]
       modalForWindow: [aComboBox window]
        modalDelegate: controller
       didEndSelector: NULL
          contextInfo: nil];
}

Код создает экземпляр RVListEditorController. Это контролирует панель, которая позволяет мне редактировать список в выпадающем списке (удалять элементы, сортировать элементы и т. Д.). Он имеет, среди прочего, две кнопки, закрывающие его, Отмена и ОК.

Код для двух кнопок:

- (IBAction) closeSheetWithOK: (id) sender
{
    [NSApp endSheet: editingPanel];
    [editingPanel orderOut: self];
    [comboBoxValues setArray: valuesCopy];
    if (comboBoxValues.count > 0)
        [editedComboBox setStringValue: [comboBoxValues objectAtIndex: 0]];
    [self release];
}


- (IBAction) closeSheetWithCancel: (id) sender
{
    [NSApp endSheet: editingPanel];
    [editingPanel orderOut: self];
    [self release];
}

Это только две кнопки, закрывающие лист. Мой вопрос касается управления жизненным циклом экземпляра. Он размещается в методе класса, но затем управление снова передается в Какао, и метод класса завершается. Единственное место, которое я смог найти для освобождения экземпляра, - это два обработчика для кнопок закрытия. Моя проблема в том, что beginSheet:modalForWindow:modalDelegate:didEndSelector:contextInfo: не просто открывает лист, а затем ждет, пока он снова не закроется, возвращая значение, как он был закрыт. Если бы это было так, я мог бы закрыть экземпляр в методе класса, и я бы чувствовал себя лучше.

Мой вопрос: возможно, есть лучший способ обработать время существования экземпляра, или в Какао есть что-то, что позволяет мне модально открыть окно листа и затем ждать, пока оно снова закроется, чтобы я мог выпустить экземпляр сразу после этого? Я не могу думать ни о чем, но я относительный новичок, в конце концов.

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

Ответы [ 3 ]

2 голосов
/ 22 июля 2011

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

1 голос
/ 23 июля 2011

Мне удалось получить то, что сработало к моему удовлетворению.Я предоставил beginSheet: метод, который вызывается после окончания листа, предоставляя контроллер в качестве контекстной информации.IOW:

    [NSApp beginSheet: [controller window]
       modalForWindow: [aComboBox window]
        modalDelegate: controller
       didEndSelector: @selector(sheetDidEnd:returnCode:contextInfo)
          contextInfo: (void *)controller];
}

Теперь код для двух кнопок:

- (IBAction) closeSheetWithOK: (id) sender
{
    [comboBoxValues setArray: valuesCopy];
    if (comboBoxValues.count > 0)
        [editedComboBox setStringValue: [comboBoxValues objectAtIndex: 0]];
    [NSApp endSheet: editingPanel];
}


- (IBAction) closeSheetWithCancel: (id) sender
{
    [NSApp endSheet: editingPanel];
}

, а код для sheetDidEnd:returnCode:contextInfo::

- (void) sheetDidEnd: (NSWindow *) sheet returnCode: (NSInteger) returnCode contextInfo: (void *) contextInfo
{
    [sheet orderOut: (id)contextInfo];
    [(id)contextInfo release];
}

То естьИМО, лучшее, что можно сделать для подобных ситуаций.Процедура была бы такой же, если бы она была вызвана из метода экземпляра контроллера окна, AFAICT.

1 голос
/ 22 июля 2011

Я просто не очень доволен той конструкцией, в которой я выделяю что-то в методе класса, который затем должен быть освобожден в двух методах самого экземпляра.

В этом есть определенная логика - но я бы также сказал, что оконно-модальный лист более естественно будет инициирован методом экземпляра. В конце концов, окно - это представление какого-то объекта, а не просто класса.

Это не ответило на ваш более общий вопрос о жизненных циклах.

...