iOS 12 Safari では配列の状態がキャッシュされます。これはバグですか、それとも機能ですか? 質問する

iOS 12 Safari では配列の状態がキャッシュされます。これはバグですか、それとも機能ですか? 質問する

2018.10.31更新

このバグはiOS 12.1で修正されました。良い一日をお過ごしください〜

新しくリリースされた iOS 12 Safari で、配列の値の状態に問題があることがわかりました。たとえば、次のようなコードです。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
    <title>iOS 12 Safari bugs</title>
    <script type="text/javascript">
    window.addEventListener("load", function ()
    {
        let arr = [1, 2, 3, 4, 5];
        alert(arr.join());

        document.querySelector("button").addEventListener("click", function ()
        {
            arr.reverse();
        });
    });
    </script>
</head>
<body>
    <button>Array.reverse()</button>
    <p style="color:red;">test: click button and refresh page, code:</p>
</body>
</html>

ページを更新した後も、配列の値は逆になっています。これはバグでしょうか、それとも新しい Safari の機能でしょうか?


こちらはデモページです。iOS 12 Safari で使用してみてください。参考:

ベストアンサー1

それは間違いなくバグです! そして非常に深刻なバグです。

このバグは、すべての値がプリミティブ リテラルである配列初期化子の最適化が原因です。たとえば、次の関数があるとします。

function buildArray() {
    return [1, null, 'x'];
}

の呼び出しから返されるすべての配列参照はbuildArray()同じメモリにリンクされ、などの一部のメソッドtoString()は結果をキャッシュします。通常、一貫性を保つために、このような最適化された配列に対する変更可能な操作はデータを別のメモリ領域にコピーしてリンクします。このパターンはコピーオンライト、略して CoW とも呼ばれます。

このreverse()メソッドは配列を変更するため、コピーオンライトをトリガーするはずです。しかし、元の実装者 (Apple の Keith Miller) がreverse()多くのテストケースを作成したにもかかわらず、このケースを見逃したため、コピーオンライトはトリガーされませんでした。

このバグはアップルに報告8月21日。修正WebKitリポジトリに登場2018 年 8 月 27 日にリリースされ、2018 年 10 月 30 日に Safari 12.0.1 および iOS 12.1 で出荷されました。

おすすめ記事