Каков наилучший способ сделать более одного объекта делегатом другого объекта?

Я создаю приложение для iOS с 4 вкладками (4 контроллера представления), которое получает обновления CoreLocation и отображает местоположение вместе с некоторыми другими данными в различных представлениях (представление таблицы, представление карты и т. Д.)

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

Каков наилучший способ сообщить контроллерам представления о том, что произошло обновление местоположения?

3 ответа

Решение

Лучший метод, вероятно, просто использовать центр уведомлений. Скорее чем @protocolположить NSString * const вы используете для уведомления:

NSString * const kMyNotificationString @"MyNotificationString"

Теперь, когда потенциальные делегаты должны ответить, это так просто:

[[NSNotificationCenter defaultCenter] postNotificationName:kMyNotificationString
                                                    object:nil];

Любой объект, который должен ответить на это уведомление, может #import этот заголовочный файл (поэтому он получает NSString * constимя уведомления, а затем и начать слушать уведомление как таковое:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(myMethod)
                                             name:kMyNotificationString
                                           object:nil];

Только не забудьте удалить наблюдателей, когда (или до) вы освободите.


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

Вместо одного свойства делегата, вы могли бы иметь NSArray свойство, которое обрабатывает "делегаты" (убедитесь, что у вас есть метод "addDelegate", который добавляет только слабые ссылки в массив). Затем, когда вам понадобятся все эти объекты, чтобы ответить на изменение:

for (id<MyProtocol> object in self.arrayOfDelegates) {
    if ([object respondsToSelector:@selector(myMethod)]) {
        [object myMethod];
    }
}

Самое простое - это опубликовать уведомление, а не использовать делегата. Делегаты 1:1, а уведомления 1: много. Проблема в том, что вам все еще нужен хотя бы один делегат, который будет публиковать уведомления.

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

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

Другие вопросы по тегам