Так вы можете объяснить мне, в чем разница между ними? а также ! в authorObj! .book? .author = authorObj и authorObj! .book! .author = authorObj?
Когда вы используете ?
для разворачивания необязательного объекта, это называется необязательной цепочкой. Если необязательный параметр nil
, результатом всей цепочки будет nil
. Преимущество использования ?
заключается в том, что ваше приложение не выйдет из строя, если разворачиваемое значение равно nil
.
So:
authorObj!.book?.author = authorObj
произойдет сбой, если authorObj
равно nil
(из-за принудительного развертывания !
).
а также:
authorObj!.book!.author = authorObj
произойдет сбой, если authorObj
или book
равно nil
.
Безопасный способ написать это:
authorObj?.book?.author = authorObj
Если authorObj
или book
равно nil
, ничего не будет и не произойдет сбой.
authorObj - это сильная ссылка, такая же, как и authorObj.book.author, это тоже сильная ссылка? Потому что у него нет weak или unowned до var.
Когда речь идет о слабом и сильном, имеет смысл говорить только об одной переменной. Нет смысла спрашивать, является ли authorObj.book
слабым; можно сказать, что Author
содержит слабую ссылку на book
.
Только authorObj.book - слабая ссылка. Но когда я присваиваю authorObj значение nil, все деинициализируются. Почему? Я присваиваю nil только authorObj, но экземпляр 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
. Почему? Потому что на него нет сильных указателей. Вы выделили его, а затем назначили единственную ссылку на него weak указателю внутри 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
authorObj
на шаге four
, он не был освобожден до тех пор, пока book
не был освобожден после шага five
.
Локальная переменная book
содержит строгую ссылку на Book()
, а Book
содержит строгую ссылку на Author
, поэтому, когда мы присваиваем nil
authorObj
на шаге four
, authorObj
не может быть освобожденным, потому что book
по-прежнему содержит сильную ссылку на него. Когда test
завершается, локальная переменная book
освобождается, поэтому строгая ссылка на authorObj
освобождается, и, наконец, authorObj
может быть освобожден, поскольку последняя сильная ссылка на нее исчезла.
person
vacawama
schedule
19.06.2016