Skip to content

Instantly share code, notes, and snippets.

@nikolaykasyanov
Last active April 3, 2019 11:56
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nikolaykasyanov/5f069fcc894deec6a8898f249bc82cb0 to your computer and use it in GitHub Desktop.
Save nikolaykasyanov/5f069fcc894deec6a8898f249bc82cb0 to your computer and use it in GitHub Desktop.

Self в Swift и Objective-C

Дисклеймер: речь идёт об однопоточном коде, оставим ужасы параллельного исполнения за скобками. Также не рассматривается возможность overrelease.

Objective-C

Объект точно не ритейнится на время выполнения его метода, пруфы:

Нюанс: если в строке 48 использовать __weak вместо __unsafe_unretained, нода не разрушается внутри метода. Почему? Потому что доступ по __weak ссылке, в отличие от __unsafe_unretained, создаёт временную сильную ссылку (посредством вызова objc_loadWeakRetained).

Следовательно, пострадать в такой ситуациии можно только в случае, если сообщение объекту посылается через __unsafe_unretained ссылку. В Cocoa всё ещё есть такие делегаты, например.

Swift

Пока нет точной информации, ритейнится ли объект на время выполнения им метода.

Однако, вызов метода объекту через слабую ссылку (вроде self?.method()) можно "десахаризовать" так:

if let self = self { self.method() }

Очевидно, что внутри скоупа существует сильная ссылка на self, следовательно, любой код в method не приведёт к преждевременному разрушению self. Следовательно, независимо от того, ритейнится ли self методами, вызов метода через слабую ссылку безопасен.

Учитывая, как реализованы unowned-ссылки в Swift, они также безопасны с точки зрения разрушения объекта во время выполнения метода как и weak.

Однако, если Swift-объект используется в качестве делегата, и делегат объявлен как __unsafe_unretained, в принципе возможна та же ситуаиция, что и в Objective-C (источник не указан X дней).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment