Acabo de actualizar a Xcode 13.3 y veo varias instancias de una nueva advertencia que no había visto con versiones anteriores de Xcode. Como ejemplo, tengo una celda de vista de tabla simple llamada LabelAndSwitchTableViewCell que se ve así:
import UIKit class LabelAndSwitchTableViewCell: UITableViewCell { private let label: UILabel = { let label = UILabel() label.translatesAutoresizingMaskIntoConstraints = false return label }() private let _switch: UISwitch = { let _switch = UISwitch() _switch.translatesAutoresizingMaskIntoConstraints = false _switch.addTarget(self, action: #selector(didToggleSwitch), for: .valueChanged) return _switch }() override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) contentView.addSubview(label) contentView.addSubview(_switch) // layout constraints removed for brevity } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } @objc private func didToggleSwitch() { print("Switch was toggled...") } }Como puede ver, estoy agregando un objetivo al interruptor al que quiero que se llame cuando cambie el valor de los interruptores:
_switch.addTarget(self, action: #selector(didToggleSwitch), for: .valueChanged)Después de actualizar a Xcode 13.3, ahora veo una nueva advertencia en esta línea:
'self' refers to the method 'LabelAndSwitchTableViewCell.self', which may be unexpectedLa sugerencia de Xcode para silenciar esta advertencia es reemplazar:
_switch.addTarget(self, action: #selector(didToggleSwitch), for: .valueChanged)...con...
_switch.addTarget(LabelAndSwitchTableViewCell.self, action: #selector(didToggleSwitch), for: .valueChanged)Hacer este cambio silencia la advertencia, pero también hace que la aplicación se bloquee (selector no reconocido) cuando alterno el interruptor. Aquí está el volcado de ese accidente:
[app_mockup.LabelAndSwitchTableViewCell didToggleSwitch]: unrecognized selector sent to class 0x1043d86e8 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[app_mockup.LabelAndSwitchTableViewCell didToggleSwitch]: unrecognized selector sent to class 0x1043d86e8' Hacer que el método didToggleSwitch() sea static evitará el bloqueo, pero no estoy seguro de por qué querría hacer eso. Obviamente, puedo revertir el cambio (de LabelAndSwitchTableViewCell.self de nuevo a solo self ), pero me pregunto si hay algo más que debería hacer para abordar esto.
Puedes arreglarlo cambiando los let a lazy var's
private lazy var _switch2: UISwitch = { let _switch = UISwitch() _switch.translatesAutoresizingMaskIntoConstraints = false _switch.addTarget(self, action: #selector(didToggleSwitch), for: .valueChanged) return _switch }()La sugerencia de corrección de Xcode es simplemente incorrecta.
El motivo es que self aún no está listo en la fase 1 de inicialización del objeto. La fase 1 es para configurar todas las propiedades almacenadas, y solo en la fase 2, puede acceder a self .
Para corregir su código, puede usar la propiedad lazy , donde se completa la fase de inicialización 1.
Aquí está la referencia: https://docs.swift.org/swift-book/LanguageGuide/Initialization.html 
Para esta advertencia:
NSObject , self es un error cuando se usa directamente en una propiedad almacenada.NSObject , self se compila en un cierre automático (ClassXXX) -> () -> ClassXXX . Entonces, en tiempo de ejecución, self se usará como instancia actual. Pero, dado que Swift 5.6 nos advierte sobre eso, creo que la referencia de self en la propiedad almacenada de una subclase NSObject puede no estar permitida en futuras versiones de Swift. Ejemplo 1: error cuando no hay superclase 
Ejemplo 2: el yo compilado en AST
Para este código:
import Foundation class MyTest: NSObject { var myself = self }