Как я могу продемонстрировать объект зомби в Swift? - PullRequest
0 голосов
/ 29 октября 2018

Я прочитал Как продемонстрировать утечку памяти и объекты зомби в Xcode Instruments? но это для target-c. Шаги не применяются.

Из прочтения здесь Я понял, что зомби - это объекты, которые:

  • перераспределена
  • но что-то указатель все еще пытается указать на них и отправлять им сообщения.

не совсем уверен, чем это отличается от доступа к освобожденному объекту.

Я имею в виду, что в Swift вы можете сделать:

var person : Person? = Person(name: "John")
person = nil
print(person!.name)

Является ли человек освобожденным? Да!

Мы пытаемся указать на это? Да!

Так может ли кто-нибудь поделиться наиболее распространенной ошибкой, которая приводит к созданию висячего указателя?

Ответы [ 2 ]

0 голосов
/ 29 октября 2018

Атака зомби длиной менее 15 строк кода:

class Parent { }

class Child {
    unowned var parent: Parent // every child needs a parent

    init(parent: Parent) {
        self.parent = parent
    }
}

var parent: Parent? = Parent()
let child = Child(parent: parent!) // let's pretend the forced unwrap didn't happen
parent = nil // let's deallocate this bad parent
print(child.parent) // BOOM!!!, crash

Что происходит в этом коде, так это то, что Child содержит неизвестную ссылку на Parent, которая становится недействительной после освобождения Parent. Ссылка содержит указатель на более не живущего родителя (RIP) и доступ, который вызывает сбой с сообщением, похожим на это:

Неустранимая ошибка: Попытка прочитать неизвестную ссылку, но объект 0x1018362d0 уже был освобожден2018-10-29 20: 18: 39.423114 + 0200 MyApp [35825: 611433] Неустранимая ошибка: Попытка прочитать неизвестную ссылку, но объект 0x1018362d0 уже был освобожден

Примечание Код не будет работать на игровой площадке, для этого вам нужно обычное приложение.

0 голосов
/ 29 октября 2018

Это не висящий указатель или зомби. Когда вы используете !, вы говорите: «Если это ноль, то сбой». Вы не должны думать о person как о указателе в Swift. Это ценность. Это значение может быть .some(T) или .none (также называемое nil). Ни один из них не болтается. Это просто два разных явных значения. nil Свифта не имеет ничего общего с нулевыми указателями на других языках. Вылетает, как нулевые указатели, только когда вы явно просите об этом.

Для создания зомби вам нужно использовать что-то вроде Unmanaged. Это очень редко встречается в Swift.

...