では、何が違うのか説明してもらえますか? と !authorObj!.book?.author = authorObj および authorObj!.book!.author = authorObj?
オプションのラップを解除するために使用する場合、オプションのチェーン?
と呼ばれます。オプションが の場合、チェーン全体の結果は になります。を使用する利点は、アンラップされる値が の場合にアプリがクラッシュしないことです。nil
nil
?
nil
そう:
authorObj!.book?.author = authorObj
authorObj
である場合はクラッシュしますnil
(強制 unwrap !
のため)。
と:
authorObj!.book!.author = authorObj
authorObj
またはbook
がの場合にクラッシュしますnil
。
これを安全に記述する方法は次のとおりです。
authorObj?.book?.author = authorObj
authorObj
またはbook
である場合nil
、これは何もせず、クラッシュしません。
authorObj は authorObj.book.author と同じ強参照ですが、これも強参照ですか? var の前に弱いまたは所有されていないためです。
弱い対強いについて話すときは、単一の変数について話すことだけが理にかなっています。authorObj.book
が弱いかどうかを尋ねるのは意味がありません。への弱い参照をAuthor
保持していると言えます。book
authorObj.book のみ弱参照です。しかし、authorObj を nil に割り当てると、すべてが初期化されます。なんで?authorObj のみを nil に割り当てますが、 Author() インスタンスにはまだ 1 つの強力な参照 authorObj.book.author があります
に代入nil
するとauthorObj
、それが への最後の強力な参照であったauthorObj
ため、自動参照カウント (ARC)は参照カウンターをデクリメントしてから、 内のすべての参照を解放しますauthorObj
。それらが強い参照である場合、参照カウントが減少し、それがそのオブジェクトへの最後の参照である場合、オブジェクトも解放されます。他のオブジェクトが、解放されたオブジェクトへの弱い参照を保持している場合、 ARCはその値をnil
すべての弱いポインターに設定します。
プレイグラウンドでこれをテストするには、呼び出された関数内にコマンドを配置し、ステートメントtest
を追加print
して、いつ何が起こるかを確認できるようにします。
class Author {
weak var book: Book?
deinit {
print("Dealloc Author")
}
}
class Book {
var author: Author?
deinit {
print("Dealloc Book")
}
}
func test() {
print("one")
var authorObj: Author? = Author()
print("two")
authorObj!.book = Book()
print("three")
authorObj!.book?.author = authorObj
print("four")
}
test()
出力:
one
two
Dealloc Book
three
four
Dealloc Author
注意すべきことは、Book
step の前に割り当てが解除されることthree
です。なんで?そこに有力な手がかりがないからです。それを割り当ててから、それへの唯一の参照をAuthor内の弱いポインターに割り当てたので、ARCはすぐにそれを解放しました。
これは、割り当てられたばかりの が解放されたauthorObj!.book!.author = authorObj
ため、クラッシュする理由を説明しています。authorObj!.book
nil
Book
Book()
次に、ローカル変数に割り当ててみbook
ます。
func test() {
print("one")
var authorObj: Author? = Author()
print("two")
let book = Book()
authorObj!.book = book
print("three")
authorObj!.book?.author = authorObj
print("four")
authorObj = nil
print("five")
}
test()
今回は、出力がかなり異なります。
one
two
three
four
five
Dealloc Book
Dealloc Author
現在、ローカル変数は、割り当てられた への強い参照をbook
保持しているため、すぐには解放されません。Book
nil
step で に割り当てましたがauthorObj
、 stepの後に割り当てが解除さfour
れるまで割り当てが解除されていないことに注意してください。book
five
ローカル変数book
は への強い参照を保持しBook()
、への強い参照をBook
保持しているため、ステップでに代入すると、 への強い参照がまだ保持されているため、 を解放できません。終了すると、ローカル変数が解放されるため、への強い参照が解放され、最後の強い参照がなくなったため、最終的に割り当てを解除できます。Author
nil
authorObj
four
authorObj
book
test
book
authorObj
authorObj