iOS
Swift
swift4

Swift4のExclusive Access to Memory問題

Swift2.x系で書かれていた既存のプロジェクトをSwift4へとコンバートしていたら、

var flag = true

func action(_ flag: inout Bool, completion: () -> Void) {
    flag = !flag
    completion()
}

action(&flag) {
    log.debug(flag) // ここでクラッシュ
}

というようなコードで

Simultaneous accesses to ~, but modification requires exclusive access.
Previous access (a modification) started at ~.

というメッセージが出てクラッシュするようになりました。

どうやらSwift4ではメモリへの排他アクセスが強制されるようになり、
inoutなパラメータに渡したポインタを中から参照しようとすると
同じメモリへの同時アクセスとみなされクラッシュしていた模様。

回避策

TARGETS -> Build Settings -> Swift Compiler - Code Generation

Exclusive Access to Memory

Full Enforcement (Run-time Checks in Debug Builds Only)
から
No Enforcement
に変更するとクラッシュしなくなります。

本当は同時アクセスにならないようにコード自体を見直す必要がありますが、
古いSwiftからのコンバートという点を鑑みた結果、上記の対応でお茶を濁すことにしました(

Swift4で新規アプリを開発する際はしっかり上記を意識した実装をする必要がありますね。

参考

Conflicting Access to In-Out Parameters
Enforce Exclusive Access to Memory