0

私はSwiftの初心者です。解決しなければならない問題がいくつかありますが、自分では解決できません。

ここに私にとっていくつかの問題があります:

class Author {
    weak var book: Book?        
    deinit {
        print("Dealloc Author")
    }
}

class Book {
    var author: Author?        
    deinit {
        print("Dealloc Book")
    }
}

var authorObj:Author? = Author()
authorObj!.book = Book()
authorObj!.book!.author = authorObj

これはうまくコンパイルされます:

class Author {
    weak var book: Book?        
    deinit {
        print("Dealloc Author")
    }
}

class Book {
    var author: Author?        
    deinit {
        print("Dealloc Book")
    }
}

var authorObj:Author? = Author()
authorObj!.book = Book()
authorObj!.book?.author = authorObj

authorObj = nil
  • では、何が違うのか説明してもらえますか? と !authorObj!.book?.author = authorObjauthorObj!.book!.author = authorObj? _

さらに 2 つの質問があります。

  • authorObjは と同じ強参照ですがauthorObj.book.author、それも強参照ですか? varを持っていないweakか、前に持っていないためです。unowned

  • authorObj.book弱参照のみです。しかし、authorObjnil に割り当てると、すべて deinit されます。なんで?authorObjnilにのみ割り当てますが、Author()インスタンスにはまだ 1 つの強力な参照がありますauthorObj.book.author

4

1 に答える 1

1

では、何が違うのか説明してもらえますか? と !authorObj!.book?.author = authorObj および authorObj!.book!.author = authorObj?

オプションのラップを解除するために使用する場合、オプションのチェーン?と呼ばれます。オプションが の場合、チェーン全体の結果は になります。を使用する利点は、アンラップされる値が の場合にアプリがクラッシュしないことです。nilnil?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

注意すべきことは、Bookstep の前に割り当てが解除されることthreeです。なんで?そこに有力な手がかりがないからです。それを割り当ててから、それへの唯一の参照をAuthor内の弱いポインターに割り当てたので、ARCはすぐにそれを解放しました。

これは、割り当てられたばかりの が解放されたauthorObj!.book!.author = authorObjため、クラッシュする理由を説明しています。authorObj!.booknilBook


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

nilstep で に割り当てましたがauthorObj、 stepの後に割り当てが解除さfourれるまで割り当てが解除されていないことに注意してください。bookfive

ローカル変数bookは への強い参照を保持しBook()、への強い参照をBook保持しているため、ステップでに代入すると、 への強い参照がまだ保持されているため、 を解放できません。終了すると、ローカル変数が解放されるため、への強い参照が解放され、最後の強い参照がなくなったため、最終的に割り当てを解除できます。AuthornilauthorObjfourauthorObjbooktestbookauthorObjauthorObj

于 2016-06-19T10:47:50.957 に答える