[Bug] リスト走査中にリストの内容が変化しちゃうパターン

Posted: 2014-07-01
Category: BugPattern
Tags: #AS3

概要

例えば Event の dispatcher 的な何かが

// 疑似コード
function dispatchEvent(eventArgs) {
    for each (var callback in _listenerCallbacks) {
        callback(eventArgs);
    }
}

みたいに登録されてる _listenerCallbacks を走査して Event 投げるようなとき。

ここで callback 呼んでる先でこの dispatcher に addEventListener とか removeEventListener 的なことがされていると、_listenerCallbacks の内容が変化して呼ばれるべきものが呼ばれなくなったり、 その逆が起こったりする。

解決策

外から変更されうるものは走査対象にしない。複製したリストに対して走査する。

function dispatchEvent(eventArgs) {
    // duplicate list
    var workingCallbacks = _listenerCallbacks.slice();

    for each (var callback in workingCallbacks) {
        callback(eventArgs);
    }
}