我是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 = authorObj
authorObj!.book!.author = authorObj


我还有两个问题:


authorObj是与authorObj.book.author相同的强引用,它也是强引用吗?因为它在var之前没有weakunowned
authorObj.book是弱引用。但是,当我将authorObj分配为nil时,将全部取消初始化。为什么?我仅将authorObj分配给nil,但Author()实例仍然具有1个强引用authorObj.book.author

最佳答案

你们能为我解释一下,两者之间有何不同?和!在
  authorObj!.book?.author = authorObj和authorObj!.book!.author =
  authorObj?


当您使用?解开可选文件时,这称为可选链接。如果可选为nil,则整个链的结果将为nil。使用?的优点是,如果展开的值为nil,您的应用程序不会崩溃。

所以:

authorObj!.book?.author = authorObj


如果authorObjnil,则将崩溃(由于强制展开!)。

和:

authorObj!.book!.author = authorObj


如果authorObjbooknil,将崩溃。

编写此代码的安全方法是:

authorObj?.book?.author = authorObj


如果authorObjbooknil,则不会执行任何操作,也不会崩溃。


  authorObj是与authorObj.book.author相同的强大参考,它是
  有很强的参考价值吗?因为它在var之前没有弱者或无主者。


在谈论弱者与强者时,只谈论一个变量才有意义。询问authorObj.book是否弱是没有道理的。您可以说Authorbook的引用很弱。


  仅authorObj.book是弱引用。但是当我将authorObj分配给
  零,所有都被初始化。为什么?我只将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在步骤three之前被释放。为什么?因为没有强大的指针可以指向它。您分配了它,然后将对它的唯一引用分配给Author内部的弱指针,因此ARC立即释放了它。

这就解释了为什么authorObj!.book!.author = authorObj崩溃的原因,因为authorObj!.booknil,因为刚刚分配给它的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中将authorObj分配给了four,它也没有被释放,直到在步骤book之后将five释放之后。

局部变量book拥有对Book()的强引用,而Book拥有对Author的强引用,因此,当我们在步骤nil中将authorObj分配给four时,authorObj可以无法释放,因为book仍然对其有很强的引用。当test结束时,将释放局部变量book,因此将释放对authorObj的强引用,最后,由于对它的最后一个强引用消失了,最终可以将authorObj释放。

10-04 21:27