Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

457
Visualizações
Xcode 13.3 warning: "'self' refers to the method '{object}.self', which may be unexpected

I just updated to Xcode 13.3 and I'm seeing several instances of a new warning that I've not seen with previous versions of Xcode. As an example, I have a simple table view cell named LabelAndSwitchTableViewCell that looks like this:

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...")
    }
}

As you can see, I'm adding a target to the switch that I want to be called when the value of the switches changes:

_switch.addTarget(self, action: #selector(didToggleSwitch), for: .valueChanged)

After updating to Xcode 13.3, I'm now seeing a new warning on this line:

'self' refers to the method 'LabelAndSwitchTableViewCell.self', which may be unexpected

Xcode's suggestion to silence this warning is to replace:

_switch.addTarget(self, action: #selector(didToggleSwitch), for: .valueChanged)

...with...

_switch.addTarget(LabelAndSwitchTableViewCell.self, action: #selector(didToggleSwitch), for: .valueChanged)

Making this change does silence the warning but it also causes the app to crash (unrecognized selector) when I toggle the switch. Here's the dump from that crash:

[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'

Making the didToggleSwitch() method static will prevent the crash but I'm not sure why I'd want to do that. I can obviously revert the change (from LabelAndSwitchTableViewCell.self back to just self) but I'm wondering if there's something else that I should be doing to address this?

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

You can fix by changing the lets to lazy var's

private lazy var _switch2: UISwitch = {
    let _switch = UISwitch()
    _switch.translatesAutoresizingMaskIntoConstraints = false
    _switch.addTarget(self, action: #selector(didToggleSwitch), for: .valueChanged)
    return _switch
}()

The Xcode fix-it suggestion is just wrong.

over 4 years ago · Santiago Trujillo Relatório

0

The reason is self is not ready yet in phase 1 of object initialisation. Phase 1 is to set all stored properties, and only in phase 2, you can access to self.

To fix your code, you can use lazy property, where the initialisation phase 1 is completed.

Here is the reference: https://docs.swift.org/swift-book/LanguageGuide/Initialization.html enter image description here

For this warning:

  1. If there is no super class, or the super class is not NSObject, self is an error when to use in a stored property directly.
  2. If the super class is NSObject, self gets compiled to an auto closure (ClassXXX) -> () -> ClassXXX. So in runtime, self will be used as current instance. But, since Swift 5.6 is warning us on that, I think the reference of self in stored property of a NSObject subclass may not be allowed in future swift versions.

Example 1: error when there is no super class enter image description here

Example 2: the compiled self in AST

For this code:

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

Here is part of the compiled AST: enter image description here

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda