The Swift 5 release

The Swift 5 release enables runtime checking of Exclusive Access to Memory by default in Release builds, further enhancing Swifts capabilities as a safe language. In Swift 4, these runtime checks were only enabled in Debug builds. In this post, Ill first explain what this change means for Swift developers before delving into why it is essential to Swifts strategy for safety and performance.


To achieve memory safety, Swift requires exclusive access to a variable in order to modify that variable. In essence, a variable cannot be accessed via a different name for the duration in which the same variable is being modified as an inout argument or as self within a mutating method.

In the following example, count is accessed for modification by passing it as an inout argument. The exclusivity violation occurs because the modifier closure both reads the captured count variable and is called within the scope of the same variables modification. Inside the modifyTwice function, the count variable may only be safely accessed via the value inout argument, and within the modified closure it may only safely be accessed as $0.


在下面的示例中,通过将count作为inout参数传递,可以访问它进行修改。发生独占性冲突的原因是修饰符闭包同时读取捕获的count变量,并在同一变量的修改范围内调用。在modifytwice函数内部,只能通过value inout参数安全地访问count变量,并且在修改后的闭包内,只能安全地访问它$0

func modifyTwice(_ value: inout Int, by modifier: (inout Int) -> ()) {

func testCount() {
var count = 1
modifyTwice(&count) { $0 += count }

As is often the case with exclusivity violations, the programmers intention is somewhat ambiguous. Do they expect count to be printed as 3 or 4? Either way, the compiler does not guarantee the behavior. Worse yet, compiler optimizations can produce subtly unpredictable behavior in the presence of such errors. To protect against exclusivity violations and to allow the introduction of language features that depend on safety guarantees, exclusivity enforcement was first introduced in Swift 4.0: SE-0176: Enforce Exclusive Access to Memory.

Compile-time (static) diagnostics catch many common exclusivity violations, but run-time (dynamic) diagnostics are also required to catch violations involving escaping closures, properties of class types, static properties, and global variables. Swift 4.0 provided both compile-time and run-time enforcement, but run-time enforcement was only enabled in Debug builds.

In Swift 4.1 and 4.2, compiler diagnostics were gradually strengthened to catch more and more of the cases in which programmers could skirt exclusivity rulesmost notably by capturing variables in nonescaping closures or by converting nonescaping closures to escaping closures. The Swift 4.2 announcement, Upgrading exclusive access warning to be an error in Swift 4.2, explains some of the common cases affected by the newly enforced exclusivity diagnostics.

Swift 5 fixes the remaining holes in the language model and fully enforces that model1. Since run-time exclusivity enforcement is now enabled by default in Release builds, some Swift programs that previously appeared well-behaved, but werent fully tested in Debug mode, could be affected.

与经常发生的侵犯排他性的情况一样,程序员的意图有些模棱两可。他们是否希望计数打印为“3”或“4”?不管怎样,编译器都不能保证该行为。更糟的是,编译器优化可能会在出现此类错误时产生不可预测的微妙行为。为了防止侵犯排他性并允许引入依赖于安全保证的语言功能,在Swift 4.0:SE-0176:Enforce exclusive access to memory中首次引入了排他性强制。


Swift 4.14.2中,编译器诊断逐渐得到加强,以捕获越来越多的程序员可以绕过排他性规则的情况,尤其是通过捕获非捕获闭包中的变量或将非捕获闭包转换为转义闭包。Swift4.2公告将独占访问警告升级为Swift4.2中的错误,解释了一些受新强制的独占性诊断影响的常见情况。


Loading Disqus comments...
Table of Contents