XMPPMulticastDelegate: Handle modifications of the delegates array

This commit is contained in:
Florian Zeitz 2013-03-26 23:58:22 +01:00
parent aa5109a788
commit 61654304ed
2 changed files with 28 additions and 14 deletions

View file

@ -30,6 +30,7 @@
@interface XMPPMulticastDelegate: OFObject @interface XMPPMulticastDelegate: OFObject
{ {
OFDataArray *_delegates; OFDataArray *_delegates;
size_t handlerIndex;
} }
/** /**

View file

@ -61,28 +61,36 @@
size_t i, count = [_delegates count]; size_t i, count = [_delegates count];
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
if (items[i] == delegate) { if (items[i] != delegate)
[_delegates removeItemAtIndex: i]; continue;
return;
} [_delegates removeItemAtIndex: i];
if (i <= handlerIndex)
handlerIndex--;
return;
} }
} }
- (BOOL)broadcastSelector: (SEL)selector - (BOOL)broadcastSelector: (SEL)selector
withObject: (id)object withObject: (id)object
{ {
size_t count = [_delegates count];
id *items = [_delegates items]; id *items = [_delegates items];
size_t i, count = [_delegates count];
BOOL handled = NO; BOOL handled = NO;
for (i = 0; i < count; i++) { for (handlerIndex = 0; handlerIndex < count; handlerIndex++) {
if (![items[i] respondsToSelector: selector]) id responder = items[handlerIndex];
if (![responder respondsToSelector: selector])
continue; continue;
BOOL (*imp)(id, SEL, id) = (BOOL(*)(id, SEL, id)) BOOL (*imp)(id, SEL, id) = (BOOL(*)(id, SEL, id))
[items[i] methodForSelector: selector]; [responder methodForSelector: selector];
handled |= imp(items[i], selector, object); handled |= imp(responder, selector, object);
// Update count and items, since the handler might have
// changed them.
count = [_delegates count];
items = [_delegates items];
} }
return handled; return handled;
@ -92,18 +100,23 @@
withObject: (id)object1 withObject: (id)object1
withObject: (id)object2 withObject: (id)object2
{ {
size_t count = [_delegates count];
id *items = [_delegates items]; id *items = [_delegates items];
size_t i, count = [_delegates count];
BOOL handled = NO; BOOL handled = NO;
for (i = 0; i < count; i++) { for (handlerIndex = 0; handlerIndex < count; handlerIndex++) {
if (![items[i] respondsToSelector: selector]) id responder = items[handlerIndex];
if (![responder respondsToSelector: selector])
continue; continue;
BOOL (*imp)(id, SEL, id, id) = (BOOL(*)(id, SEL, id, id)) BOOL (*imp)(id, SEL, id, id) = (BOOL(*)(id, SEL, id, id))
[items[i] methodForSelector: selector]; [responder methodForSelector: selector];
handled |= imp(items[i], selector, object1, object2); handled |= imp(responder, selector, object1, object2);
// Update count and items, since the handler might have
// changed them.
count = [_delegates count];
items = [_delegates items];
} }
return handled; return handled;