Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

443
Views
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 answers
Answer question

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!