有什么不同?而且!在Swift中弱,强的参考

时间:2016-06-19 08:02:11

标签: swift reference null weak

我是 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

1 个答案:

答案 0 :(得分:1)

  

那么你们能为我解释一下,有什么不同之处?而且!在   authorObj!.book?。author = authorObj and 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是否是没有意义的;您可以说Author拥有对book引用。

  

只有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包含对{{1}的引用因此,当我们在步骤Author中将nil分配给authorObj时,four无法释放,因为authorObj仍然拥有引用它。当book结束时,将释放局部变量test,因此释放了对book引用,最后可以释放authorObj authorObj最后的引用已经消失。