Общение между объектами - передача себя другому объекту / Objective-C, Какао - PullRequest
3 голосов
/ 04 июня 2009

Допустим, у нас есть первый объект 'Controller', и он инициализирует другой объект с именем 'Tasks', передавая "self" для справки. Объект Tasks теперь может связываться и отправлять сообщения суперобъекту Controller. Это правильно для общения между объектами? Так обычно делают? Я только начал изучать программирование, поэтому мне интересно, все ли в порядке. До этого момента я полагался на делегатов и уведомления. Это хорошая практика?

Пример:

// Controller Object
task = [[Task alloc] initWithController: self];
- (void) runMethod: (NSString *) incoming {
NSLog(@"%@", incoming);
}

// Task Object
- (id) initWithController: (Controller *) ctrlr {
controllerPointer = ctrlr;
[controllerPointer runMethod:@"hello"];
return self
}


// All this should print out "hello"

А есть ли другие способы общения, взаимодействия между объектами?

Ответы [ 3 ]

7 голосов
/ 04 июня 2009

Это не обычный способ взаимодействия объектов контроллера (Controller в вашем примере) и объектов модели (Task). Существует множество интерпретаций паттерна Model-View-Controller (MVC), но, вообще говоря, объекты контроллера наблюдают или запрашивают объекты модели, а не полагаются на модели, чтобы узнать, кто их контроллеры, и ожидают, что они будут взаимодействовать напрямую. с ними.

Ваш дизайн создает излишне тесную связь между моделью и объектами контроллера. Что произойдет в будущем, если, например, вы решите добавить второй контроллер для управления другим представлением задач? Будут ли ваши Task объекты управлять связью с несколькими контроллерами? Это может привести к написанию большого количества кода, если у вас есть значительное количество объектов модели.

В Какао существует два основных способа объявления объектами модели событий, представляющих интерес для остальной части программы: уведомления и наблюдение значения ключа (KVO). Уведомления очень просты. Вы создаете уведомления с именем и соответствующим объектом модели, а затем публикуете их в общем NSNotificationCenter. Оттуда центр уведомлений отвечает за доставку сообщений любым объектам, которые на них подписываются.

КВО немного сложнее объяснить. По сути, за кулисами у Какао есть механизм для обнаружения изменений в объектах и ​​отправки обновленных значений непосредственно классам, которые их наблюдают. (KVO также является частью основы привязки какао, которой, к сожалению, нет в iPhone SDK)

Однако обе эти технологии объединяют то, что они предоставляют общий механизм для информирования любых других объектов о том, что что-то интересное произошло в модельном объекте. То, как эти объекты решили реагировать, полностью зависит от его решения.

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

2 голосов
/ 04 июня 2009

Это хорошая практика?

Конечно. В этом нет ничего плохого.

Если вы не используете GC, вам нужно подумать, хотите ли вы, чтобы ваш Task объект сохранил ваш объект контроллера, но в приведенном вами примере вы почти наверняка не захотите, так как ваш Controller объект будет сохранять ваш Task объект, и вы не хотите сохранять цикл.

Небольшой комментарий в стиле: я бы не использовал controllerPointer в качестве имени переменной. Я бы просто использовал controller.

А есть ли другие способы общения, взаимодействия между объектами?

Итак, вы описали использование уведомлений, которое подходит, если в уведомлении может заинтересоваться несколько объектов, а не один конкретный. Делегаты уместны, если объекту Task действительно все равно, к какому классу относится делегат.

Другой подход, который иногда имеет смысл, заключается в том, если Controller является одноэлементным, в этом случае вы можете сделать это с помощью объекта Task.

[[Controller sharedInstance] runMethod:@"hello"];

Сказав это, я думаю, что лучше хранить контроллер как переменную.

1 голос
/ 22 февраля 2011

То, что я делал в последнее время, включало протокол, который я создал для управления связью, очень как вы указываете. Это позволяет мне разделить модель и контроллер на 100% действительную проблему.

#import <Foundation/Foundation.h>


@protocol MMNotificationDelegate <NSObject>
- (void)acquireForwardClass:(id)f_class;
- (void)notifyForwardClass:(NSDictionary*)dict;
@end

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...