[Swift] Memory Safety
7590 ワード
Memory Safety
デフォルトでは、SWIFTはコード内の不安全な動作を阻止します.たとえば、初期化前に変数が使用されないようにし、メモリが解放(解放)された後に変数にアクセスせず、配列内のインデックスが範囲外であるかどうかを確認します.
SWIFTは、競合を防止するために同じメモリ領域に同時にアクセスできます.SWIFTはメモリを自動的に管理できるため、メモリへのアクセスを考慮する必要はほとんどありませんが、メモリの競合が発生する可能性があることを理解することが重要です.
Understanding Conflicting Access to Memory
同時アクセスは、主にinout
パラメータの関数または構造を使用する方法または変異方法で発生する.
Conflicting Access to In-Out Parameters
For example:var stepSize = 1
func increment(_ number: inout Int) { // write access
number += stepSize // read access
}
increment(&stepSize)
// Error: conflicting accesses to stepSize
number
はinout
パラメータなので、関数を呼び出すときはwrite accessリファレンスメモリを使用してください.
function内部では、stepSize
がメモリにアクセスして読み取りアクセスを行うが、write accessなどのメモリ位置を参照するとメモリ競合(競合)が発生する.
Conflicting Access to self in Methods
A mutating method on a structure has write access to self for the duration of the method call. For example, consider a game where each player has a health amount, which decreases when taking damage, and an energy amount, which decreases when using special abilities.struct Player {
var name: String
var health: Int
var energy: Int
static let maxHealth = 10
mutating func restoreHealth() {
health = Player.maxHealth
}
}
func balance(_ x: inout Int, _ y: inout Int) {
let sum = x + y
x = sum / 2
y = sum - x
}
extension 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
上記の例では、balance
関数を呼び出すと、2つのinout
パラメータがwrite accessを使用してメモリを参照しますが、異なる場所のメモリにアクセスするため、競合は発生しません.
ただし、oscar
を関数のパラメータとして渡すと、競合が発生します.oscar.shareHealth(with: &oscar)
// Error: conflicting accesses to oscar
mutatingメソッドでは、self
の書き込みアクセスが必要です.inout
パラメータを使用してself
、すなわちoscar
を渡すと、同じメモリ位置が参照されるため、2つの書き込みアクセスが競合します.
Reference
Memory Safety
Reference
この問題について([Swift] Memory Safety), 我々は、より多くの情報をここで見つけました
https://velog.io/@lena_/Swift-Memory-Safety
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
var stepSize = 1
func increment(_ number: inout Int) { // write access
number += stepSize // read access
}
increment(&stepSize)
// Error: conflicting accesses to stepSize
struct Player {
var name: String
var health: Int
var energy: Int
static let maxHealth = 10
mutating func restoreHealth() {
health = Player.maxHealth
}
}
func balance(_ x: inout Int, _ y: inout Int) {
let sum = x + y
x = sum / 2
y = sum - x
}
extension 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
oscar.shareHealth(with: &oscar)
// Error: conflicting accesses to oscar
Memory Safety
Reference
この問題について([Swift] Memory Safety), 我々は、より多くの情報をここで見つけました https://velog.io/@lena_/Swift-Memory-Safetyテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol