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

我还有两个问题:

  • authorObj是强参考一样authorObj.book.author吗,它也是强参考吗?因为它没有weakunowned在var之前。

  • 只有authorObj.book弱参考。但是当我分配authorObj给 nil 时,所有的都被定义了。为什么?我只分配authorObj给 nil 但Author()实例仍然有 1 个强引用authorObj.book.author

4

1 回答 1

1

那么你们能帮我解释一下,两者之间有什么不同吗?和 !在 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

如果authorObjor bookis nil,这将什么也不做也不会崩溃。

authorObj 和 authorObj.book.author 一样是强引用,它也是强引用吗?因为它在 var 之前没有弱或无主。

在谈论weakstrong时,谈论一个变量才有意义。authorObj.book问是否是没有意义的;你可以说它对 .Author的引用很弱book

只有 authorObj.book 是弱参考。但是当我将 authorObj 分配给 nil 时,所有的都被取消了。为什么?我只将 authorObj 分配给 nil 但 Author() 实例仍然有 1 个强引用 authorObj.book.author

当您分配nil给 时authorObj,这是对 的最后一个强引用authorObj,因此自动引用计数 (ARC)会递减引用计数器,然后释放 中的所有引用authorObj。如果这些是引用,它会减少引用计数,如果那是对该对象的最后一个引用,则该对象也被释放。如果任何其他对象持有对任何已释放对象的弱引用,则ARCnil在所有指针中设置该值。


要在操场上进行测试,请将您的命令放在一个名为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!.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,因此它不会立即被释放。

请注意,即使我们在 step中分配nil了 to ,它也不会被释放,直到 after被释放后 step 。authorObjfourbookfive

局部变量book持有对 的引用Book(),并且Book持有对 的引用,所以当我们在 step中Author赋值时nil,无法释放 ,因为仍然持有对它的引用。结束时,局部变量被释放,因此对它的引用被释放,最后可以被释放,因为对它的最后一个引用已经消失。authorObjfourauthorObjbooktestbookauthorObjauthorObj

于 2016-06-19T10:47:50.957 回答