参照による値のキャプチャ
クロージャが周囲の状態をキャプチャする方法を理解します。
「参照による値のキャプチャ」はCoddyKit上の無料Swift Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSwift Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Swift Academyコースには全4レッスンが含まれています。
クロージャーがキャプチャするもの
クロージャーは、参照している周囲のスコープにある変数や定数をキャプチャします。キャプチャされた変数は参照によって保持されるため、クロージャーから後の変更を確認できます。
定数のキャプチャ
関数が戻った後も、クロージャーはgreetingを記憶しています:
func makeGreeter() -> () -> String {
let greeting = "Hello"
return { greeting }
}
let greet = makeGreeter()
print(greet()) // "Hello"変数を参照でキャプチャする
countはvarなので、クロージャーは呼び出しをまたいで同じ記憶領域を変更します:
func makeCounter() -> () -> Int {
var count = 0
return {
count += 1
return count
}
}
let next = makeCounter()
print(next(), next(), next()) // 1 2 3共有される記憶領域
2つのクロージャーが同じ変数をキャプチャし、お互いの変更を確認できます:
func makePair() -> (() -> Void, () -> Int) {
var value = 0
let inc = { value += 1 }
let read = { value }
return (inc, read)
}
let (inc, read) = makePair()
inc(); inc()
print(read()) // 2キャプチャには後の変更が反映されます
クロージャーは、作成時の値ではなく、呼び出し時点での変数の現在の値を読み取ります:
var message = "first"
let show = { print(message) }
message = "second"
show() // "second"参照によるキャプチャと値によるキャプチャ
デフォルトでは、変更可能な変数は参照によってキャプチャされます。作成時点の値を固定したコピーが必要な場合は、キャプチャリストに[x]のように記述します。
値を固定する
キャプチャリストは値をすぐにコピーします:
var n = 10
let frozen = { [n] in n } // copies 10 now
n = 99
print(frozen()) // 10クロージャーごとに独立した状態
ファクトリを呼び出すたびに、新しくキャプチャされた変数が作られます:
func counter() -> () -> Int {
var c = 0
return { c += 1; return c }
}
let a = counter(), b = counter()
print(a(), a(), b()) // 1 2 1ループ内でのキャプチャ
注意しないと、ループ内のクロージャーが同じ変数を共有することがあります。反復ごとの値を保存するには、キャプチャリストを使います:
var closures: [() -> Int] = []
for i in 1...3 {
closures.append { [i] in i }
}
print(closures.map { $0() }) // [1, 2, 3]メソッド内で self をキャプチャする
メソッド内で作成されたクロージャーは、周囲のインスタンスをキャプチャするため、後からプロパティを読み取ったり変更したりできます:
class Bank {
var balance = 0
func deposit() -> () -> Void {
return { self.balance += 10 }
}
}
let bank = Bank()
let add = bank.deposit()
add(); add()
print(bank.balance) // 20なぜ重要なのか
参照によるキャプチャは、カウンター、アキュムレーター、状態を持つコールバックを実現します — 一方で、クロージャーがオブジェクトを生存させ続けることもあるため、次にキャプチャリストを使って管理します。
func accumulator() -> (Int) -> Int {
var total = 0
return { total += $0; return total }
}
let add = accumulator()
print(add(10), add(5)) // 10 15クイックチェック
まとめ
キャプチャの仕組みを学びました:
- クロージャーは、スコープ内で参照されている変数をキャプチャします
- 変更可能なvarは参照によってキャプチャされるため、変更や変更操作が共有されます
- キャプチャリスト
[x]を使うと、作成時点の値のコピーを固定できます - これにより、カウンターや状態を持つコールバックを実現できます
次は、エスケープするクロージャーです。
よくある質問
「参照による値のキャプチャ」レッスンは無料ですか?
はい。「参照による値のキャプチャ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Swift Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Swift Academyコースには全4レッスンが含まれています。
「参照による値のキャプチャ」で何を学びますか?
クロージャが周囲の状態をキャプチャする方法を理解します。 ブラウザで直接実行するハンズオンコードでSwift Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Swift Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのSwift Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「参照による値のキャプチャ」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このSwift Academyレッスンでコードを書いて実行できますか?
はい。すべてのSwift Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- 参照による値のキャプチャ
- エスケapingクロージャ
- キャプチャリストとweak self
- オートクロージャ