Контроллер представления не реагирует на методы действий

У меня есть простое тестовое приложение (в OSX), в котором есть контроллер представления с кнопкой в ​​его представлении. Метод действия кнопки находится в классе контроллера представления, и этот IBAction подключен к IB (через владельца файла). При нажатии кнопки я получаю ошибку EXC_BAD_Access (за исключением случая, когда я получаю - [NSRunLoop buttonClick:] вместо этого). Я прочитал здесь кучу сообщений о SO, связанных с NSViewControllers, которые не находятся в цепочке респондентов, но также о том, что конкретное подключение метода действия в IB должно работать. Единственный код, который у меня есть, это:

В делегате приложения:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    TestController *controller = [[TestController alloc] initWithNibName:@"TestController" bundle:nil];
    [self.window.contentView addSubview:controller.view];
}

А в классе TestController только это:

-(IBAction)buttonClick:(id)sender {
    NSLog(@"%@",sender);
}

У меня 2 вопроса. Почему это происходит и где правильное место mvc для размещения IBActions для методов кнопки (не должны ли классы контроллера обрабатывать это)?


person rdelmar    schedule 02.06.2012    source источник
comment
Ответ qegal, хотя и написан так, как будто вы работаете на iOS, по сути, решил бы проблему за вас. Вы помещаете созданный вами контроллер представления в локальную переменную, и он немедленно освобождается (ARC). Это означает, что при нажатии кнопка отправляет сообщение о недопустимом объекте. Если вы создадите свойство strong в делегате приложения для хранения контроллера и назначите его, все будет работать нормально. Контроллер представления обычно является правильным местом для размещения IBAction методов.   -  person jscs    schedule 04.06.2012


Ответы (3)


Во-первых, я считаю, что в App Delegate уже есть свойство с именем viewController, уже определенное для вас. Вы должны использовать этот код self.viewController = [[TestController alloc] initWithNibName:@"TestController" bundle:nil]; вместо TestController *controller = [[TestController alloc] initWithNibName:@"TestController" bundle:nil];. Если это не поможет, то я не уверен, что случилось. Ваш код должен возвращать атрибуты нажатой кнопки. Я создал свой собственный образец проекта и протестировал ваш код (хотя мой делегат приложения выглядел иначе, чем ваш), и он работал нормально.

Во-вторых, вы должны уточнить свой второй вопрос «Why is this happening, and where is the correct mvc place to put IBActions for button methods (shouldn't controller classes handle these)?». Не очень понятно, что вы имеете в виду.

Надеюсь, это немного поможет.

person pasawaya    schedule 02.06.2012
comment
Нет, в делегате приложения не определен viewController - это OSX, а не iOS. Что касается второго вопроса, я просто пытаюсь выяснить, каков правильный способ mvc для обработки методов действий из элементов управления представления. Какой класс должен реализовывать эти методы? Они работают, если я помещаю их в представление подкласса, но я понял, что представления не должны делать такого рода вещи, они предназначены только для отображения. - person rdelmar; 02.06.2012
comment
Вы должны поместить IBActions в контроллер представления, над которым должны работать IBActions. - person pasawaya; 02.06.2012
comment
Это именно то, что НЕ работает. У меня есть IBActions в моем контроллере представления. - person rdelmar; 02.06.2012
comment
Что ж, тут что-то напортачило. Это должно быть там. - person pasawaya; 03.06.2012

NSViewController не будет отвечать на IBActions в mac os x на iPhone. Это правильное место для размещения вашего IBAction, поскольку представление должно только рисовать свое содержимое (данные), а не изменять его. Но в Mac OS x NSViewController предназначен для настройки NSView, это не означает, что нужно отвечать на IBActions, у вас есть два варианта: один - поместить свой IBAction в ваш NSView или создать NSWindowController. В mac osx у вас много места на экране, и у вас всегда будут представления в окне, вы будете использовать NSViewController, чтобы добавить их в свое окно и настроить представление, но окно находится сначала в вашей цепочке респондентов, а затем в NSWindowController. например: у вас может быть одно окно и два контроллера представления, показывающие одно и то же представление, в котором может быть 5 тестовых полей, и контроллер представления, один загружает это с данными, но вы не можете редактировать данные, затем контроллер представления два загружает одно и то же представление с теми же данными но разрешите редактирование текстовых полей так. но все методы действий перейдут в WindowController.

person Apps 4 U    schedule 30.07.2012

Я рекомендую вам проверить инспектор идентичности viewController. Это может указывать на неправильный пользовательский класс. ViewController, созданный в основном, обычно имеет имя ViewController в разделе.

person serendi21    schedule 19.06.2015