最初に:print(str)
を追加すると明らかにわかるように、defer
が実行されます。今
が返された値が変更された値を反映していない理由を説明する:
この理由は
String
は不変であるということです - あなたは
str += something
を書くたびに、まったく新しい
String
インスタンスを作成し、
str
内に保管してください。
str
の現在のインスタンス(123yyy4
)を返すreturn str
を書き込むとします。その後、defer
が呼び出され、完全に新規で無関係のString
123yyy4xxx
がstr
に割り当てられます。しかし、以前のString
オブジェクトはstr
の中に格納されていたものを変更することはなく、単純に上書きするため、すでに "発生した" return
には影響しません。
あなたの代わりにあなたが常に同じインスタンス上で動作しますNSMutableString
を使用するようにする方法を変更すると発生しますので、正しく出力さ123yyy4xxx
場合:
そのコードで
func branch() -> NSMutableString {
var str = NSMutableString()
defer { str.appendString("xxx") }
str.appendString("1")
let counter = 3;
if counter > 0 {
str.appendString("2")
defer { str.appendString("yyy") }
str.appendString("3")
}
str.appendString("4")
return str
}
let bran1 = branch()
リターンはstr
に保存されたインスタンスを返します遅延はのインスタンスに変更されますが、新しいインスタンスは割り当てられませんが、すでに存在するインスタンスは変更されます。あなたはさまざまな段階でstr
のメモリアドレスを表示しようとすることができます説明の便宜上
:
return
- の時に、それを変更した後
defer
ブロック
- で
str
を変更する前
NSMutableString
の場合、3つすべてのケースで同じメモリアドレスが返されますg インスタンスは同じままです。しかし、String
は2つの異なるメモリアドレスを出力し、返されるStringはsomeAddress
を指し、遅延されたものはsomeOtherAddress
を指す。
それは動作しますが、スコープがなくなる_after_ 'defer'が呼び出され、したがって、最初に'return str'が呼び出されると、スコープがなくなり、' defer'が呼び出され、 '' xxx ''がローカルインスタンスに追加されます。 – holex