проблема с шаблоном слушателя с использованием быстрого перечисления - PullRequest
0 голосов
/ 01 сентября 2010

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

- (void) updateListeners {
for (id<AProtocol>listener in _listeners)
{
   [listener update];
}

, и в слушателе я реализую метод для AProtocol, который является обновлением.Предположим, что в _listeners есть n объектов, а число слушателей m такое, что m

Ответы [ 3 ]

4 голосов
/ 01 сентября 2010

Звучит так, как будто у вас сейчас слушатель сам решает, следует ли его удалить, и удаляет сам. Это проблематично, потому что (а) как вы говорите, это нарушает ваше перечисление, но (б) потому что это хитрая абстракция - если объект, который запускает «обновление», также не контролирует владение в списке слушателей напрямую, ваш шаблон проектирования может столкнуться с проблемами в любом случае. Я мог бы предложить переопределить слушателей обновлений следующим образом:

- (BOOL)update

и возвращает BOOL, указывающий, должен ли слушатель быть удален (или сохранен, в зависимости от вашей семантики). Тогда вы могли бы написать цикл так:

NSMutableSet * listenersToBeRemoved = [NSMutableSet set];
for (id<AProtocol> listener in _listeners) {
    BOOL shouldRemove = [listener update];
    if (shouldRemove) { 
        [listenersToBeRemoved addObject:listener];
    }
}
// Do this if _listeners is a Set, or whatever the equivalent is.
[_listeners minusSet:listenersToBeRemoved];

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

2 голосов
/ 01 сентября 2010

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

for (id<AProtocol>listener in [NSArray arrayWithArray:_listeners])
{
   [listener update];
}

Тогда _listeners можно безопасно изменить во время цикла.Это безопаснее, чем решение Davids, поскольку оно защищено от удалений слушателей, а не только тех, которые происходят в -update.

0 голосов
/ 01 сентября 2010

Заменить быструю итерацию обычной итерацией и начать с последней.

// must iterate from the last in case the current listener removes itself from the list
for (int i = [_listeners count] - 1; i > -1; i--) {
    id<AProtocol> listener = [_listeners objectAtIndex:i];
    [listener update];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...