Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

440
Vistas
Advertencia de Xcode 13.3: "'self' se refiere al método '{object}.self', que puede ser inesperado

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 unexpected

La 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.

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

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.

over 4 years ago · Santiago Trujillo Denunciar

0

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 ingrese la descripción de la imagen aquí

Para esta advertencia:

  1. Si no hay una superclase, o la superclase no es NSObject , self es un error cuando se usa directamente en una propiedad almacenada.
  2. Si la superclase es 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 ingrese la descripción de la imagen aquí

Ejemplo 2: el yo compilado en AST

Para este código:

 import Foundation class MyTest: NSObject { var myself = self }

Aquí hay parte del AST compilado: ingrese la descripción de la imagen aquí

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda