Iterating over a set of event handlers, how do you safely remove a handler from * inside * a callback?

I am a little puzzled by something. The Java documentation tells us that when deleting items from a collection while repeating this collection using an Iterator object, there is no specific behavior, and the only safe way to do this is to use Iterator.remove ().

How, then, would you safely remove an event handler from an ArrayList if, in the process of repeating in the list, one of the handlers decided that it was time to remove itself as a listener?

// in public class Dispatcher

public void dispatchEvent(){
    Iterator<IEventHandler> iterator = mHandlers.iterator();
    IEventHandler handler = null;
    while(iterator.hasNext()){
        handler = iterator.next();
        handler.onCallbackEvent();
    }
}

public void insertHandler(IEventHandler h){
    mHandlers.add(h);
}

public void removeHandler(IEventHandler h){
    mHandlers.remove(h);
}

Meanwhile, the handler was created this way ...

final Dispatcher d = new Dispatcher();
d.insertHandler(new IEventHandler(){
    @Override
    public void onCallbackEvent(){
        Log.i(" callback happened ");
        d.removeHandler(this);
    }
});

? ArrayList , onCallbackEvent() , Iterator.

? ?

+3
2

. - . insertHandler/removeHandler CopyOnWriteArrayList.

+3

removeHandler, , .

public void removeHandler(IEventHandler h){
    mHandlersToRemove.add(h);
}

.

public void dispatchEvent(){
    mHandlers.removeAll(mHandlersToRemove);
    mHandlersToRemove.clear();
    ...

dispatchEvent, . ( , .)


, , ++ . stl , .

:

for (itr = listA.begin(); itr != listA.end(); )
{
    if ( shouldRemove(*itr) ) {
        itr = listA.erase(itr);
    }
    else {
      ++itr;
    }
}

, , ++, ( " ). , , Java - :)

+2

Source: https://habr.com/ru/post/1796417/


All Articles