: 코드에서 메모리 접근이 시작되고 끝나기 전에 그 메모리에 대한 다른 접근이 시작될 수 없을 때를 의미
: 장기 접근은 시작되고 종료되기 전에 다른 코드가 실행될 수 있음 → 오버랩 overlap
func increment(_ number: inout Int) {
number += stepSize
}
increment(&stepSize)
// Error: conflicting accesses to stepSize
var copyOfStepSize = stepSize
increment(©OfStepSize)
// Update the original.
stepSize = copyOfStepSize
// stepSize is now 2
struct Player {
var name: String
var health: Int
var energy: Int
static let maxHealth = 10
mutating func restoreHealth() {
health = Player.maxHealth
// self에 쓰기 접근은 메소드 반환될 때까지 유지
}
}
extension Player {
// shareHealth(with:) 메소드는 in-out 파라미터로 다른 Player 인스턴스를 가져
// 중복 접근에 대한 가능성을 만듦
mutating func shareHealth(with teammate: inout Player) {
balance(&teammate.health, &health)
}
}
var oscar = Player(name: "Oscar", health: 10, energy: 10)
var maria = Player(name: "Maria", health: 5, energy: 10)
oscar.shareHealth(with: &maria) // OK. 중복 야기 X
// oscar는 변경 함수에서 self의 값이기 때문에 oscar에 대한 쓰기 접근
// maria는 in-out 파라미터로 전달되기 때문에 maria에 대한 쓰기 접근
// 그러나 shareHealth(with:) 의 인자로 oscar를 전달하면 충돌 발생
oscar.shareHealth(with: &oscar)
// Error: conflicting accesses to oscar
// 변경 메소드는 self에 대한 쓰기 접근이 필요, in-out 파라미터는 teammate에 쓰기 접근 필요
// 메소드 내에서 self와 teammate는 메모리의 같은 위치를 참조, 쓰기 접근 오버랩되므로 충돌
var playerInformation = (health: 10, energy: 20)
balance(&playerInformation.health, &playerInformation.energy)
// Error: conflicting access to properties of playerInformation
// playerInformation에 중복 쓰기 접근이므로 충돌
// playerInformation.health, playerInformation.energy는 쓰기 접근이 필요한 in-out 파라미터
// 전역 변수에 저장된 구조체의 프로퍼티에 쓰기 접근 중복될 때 에러
var holly = Player(name: "Holly", health: 10, energy: 10)
balance(&holly.health, &holly.energy) // Error
// holly 변수가 전역 변수가 아닌 지역 변수로 변경되면 구조체의 저장된 프로퍼티 중복 접근 안전
func someFunction() {
var oscar = Player(name: "Oscar", health: 10, energy: 10)
balance(&oscar.health, &oscar.energy) // OK
}
// 위에서 oscar의 health, energy는 2개의 in-out 파라미터로 전달
// 2개의 저장된 프로퍼티는 상호작용하지 않으므로 안전
- 계산된 프로퍼티 또는 클래스 프로퍼티가 아닌 인스턴스의 저장된 프로퍼티만 접근
- 구조체는 전역 변수가 아닌 지역 변수의 값임
- 구조체는 클로저에 의해 캡쳐되지 않거나 nonescaping 클로저에 의해서만 캡쳐됨