From 61654304eda4b6856ddd52fd146b5210d8e84ba0 Mon Sep 17 00:00:00 2001 From: Florian Zeitz Date: Tue, 26 Mar 2013 23:58:22 +0100 Subject: [PATCH] XMPPMulticastDelegate: Handle modifications of the delegates array --- src/XMPPMulticastDelegate.h | 1 + src/XMPPMulticastDelegate.m | 41 ++++++++++++++++++++++++------------- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/XMPPMulticastDelegate.h b/src/XMPPMulticastDelegate.h index c7dbbc8..306c70a 100644 --- a/src/XMPPMulticastDelegate.h +++ b/src/XMPPMulticastDelegate.h @@ -30,6 +30,7 @@ @interface XMPPMulticastDelegate: OFObject { OFDataArray *_delegates; + size_t handlerIndex; } /** diff --git a/src/XMPPMulticastDelegate.m b/src/XMPPMulticastDelegate.m index afba301..1d165f8 100644 --- a/src/XMPPMulticastDelegate.m +++ b/src/XMPPMulticastDelegate.m @@ -61,28 +61,36 @@ size_t i, count = [_delegates count]; for (i = 0; i < count; i++) { - if (items[i] == delegate) { - [_delegates removeItemAtIndex: i]; - return; - } + if (items[i] != delegate) + continue; + + [_delegates removeItemAtIndex: i]; + if (i <= handlerIndex) + handlerIndex--; + return; } } - (BOOL)broadcastSelector: (SEL)selector withObject: (id)object { + size_t count = [_delegates count]; id *items = [_delegates items]; - size_t i, count = [_delegates count]; BOOL handled = NO; - for (i = 0; i < count; i++) { - if (![items[i] respondsToSelector: selector]) + for (handlerIndex = 0; handlerIndex < count; handlerIndex++) { + id responder = items[handlerIndex]; + if (![responder respondsToSelector: selector]) continue; 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; @@ -92,18 +100,23 @@ withObject: (id)object1 withObject: (id)object2 { + size_t count = [_delegates count]; id *items = [_delegates items]; - size_t i, count = [_delegates count]; BOOL handled = NO; - for (i = 0; i < count; i++) { - if (![items[i] respondsToSelector: selector]) + for (handlerIndex = 0; handlerIndex < count; handlerIndex++) { + id responder = items[handlerIndex]; + if (![responder respondsToSelector: selector]) continue; 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;