java-在遍历事件处理程序的集合时,如何安全地从*回调中删除处理程序?

我有点不解. Java的文档告诉我们,使用Iterator对象遍历该集合时,从集合中删除项目时没有定义的行为,这样做的唯一安全方法是使用Iterator.remove().

然后,如果在遍历列表的过程中有一个处理程序确定是时候将其自身作为侦听器删除了,那么如何安全地从ArrayList中删除事件处理程序?

// 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);
}

同时,处理程序是这样实例化的.

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

看到潜在的问题了吗?由于仍在使用Iterator进行迭代时,由于在该特定处理程序中声明了onCallbackEvent(),因此要从ArrayList中删除该处理程序.

这是一个棘手的问题吗?处理这种情况的安全方法是什么?

解决方法:

在实现事件系统时,这是一个非常常见的问题.唯一的解决方案是在更改时复制处理程序列表.您可以在insertHandler / removeHandler方法中自行完成此操作,也可以只使用copyOnWriteArrayList.

相关文章

Android性能优化——之控件的优化 前面讲了图像的优化,接下...
前言 上一篇已经讲了如何实现textView中粗字体效果,里面主要...
最近项目重构,涉及到了数据库和文件下载,发现GreenDao这个...
WebView加载页面的两种方式 一、加载网络页面 加载网络页面,...
给APP全局设置字体主要分为两个方面来介绍 一、给原生界面设...
前言 最近UI大牛出了一版新的效果图,按照IOS的效果做的,页...