L’uso dell’inferenza di Swift 3 @objc nella modalità Swift 4 è deprecato?

In breve, durante l’utilizzo di Xcode 9 Beta, ho ricevuto il seguente avviso:

L’uso dell’inferenza di Swift 3 @objc nella modalità Swift 4 è deprecato. Si prega di rispondere alle avvertenze di inferenza @objc deprecate, testare il proprio codice con “Uso della registrazione deprecata di Swift 3 @objc inferenza” e disabilitare l’inferenza di Swift 3 @objc. **

Dopo alcune ricerche, non ho ancora idea di come risolvere il problema. Apprezzerei molto qualsiasi suggerimento su come risolvere questo problema e una spiegazione di cosa sta succedendo.

Il mio objective è comprendere meglio ciò che sta accadendo con il mio codice.

    Mi sono liberato di questo avviso modificando l’impostazione di build “Swift 3 @objc Inference” dei miei obiettivi su “Default”.

    Disabilita l'inferenza di Swift 3 @objc in Xcode9

    Da questo articolo :

    Prima di Swift 4, il compilatore rendeva automaticamente alcune dichiarazioni Swift disponibili su Objective-C . Ad esempio, se una sottoclass da NSObject, il compilatore ha creato i punti di ingresso Objective-C per tutti i metodi in tali classi. Il meccanismo è chiamato inferenza @objc.

    In Swift 4, tale inferenza automatica @objc è deprecata perché è costoso generare tutti quei punti di ingresso Objective-C. Quando l’impostazione “Swift 3 @objc Inference” è impostata su “On”, consente al vecchio codice di funzionare. Tuttavia, mostrerà avvisi di ritiro che devono essere risolti. Si consiglia di “correggere” questi avvisi e di commutare su “Predefinito” , che è l’impostazione predefinita per i nuovi progetti Swift.

    Si prega di fare riferimento a questa proposta Swift per ulteriori informazioni.

    – Cos’è l’inferenza di @objc ? Cosa sta succedendo?

    In Swift 3, il compilatore deduce @objc in un numero di punti in modo da non @objc fare. In altre parole, è sicuro di aggiungere @objc per te!

    In Swift 4, il compilatore non esegue più questo (tanto). Ora devi aggiungere esplicitamente @objc .

    Di default, se hai un progetto pre-Swift 4, riceverai avvertimenti su questo. In un progetto Swift 4, otterrai errori di compilazione. Questo è il controller tramite l’impostazione di build SWIFT_SWIFT3_OBJC_INFERENCE . In un progetto pre-Swift 4 questo è impostato su On . Vorrei raccomandare di impostarlo su Default (o Off ), che ora è l’opzione predefinita su un nuovo progetto.

    Ci vorrà del tempo per convertire tutto, ma dato che è l’impostazione predefinita per Swift 4, vale la pena farlo.

    – Come posso interrompere gli avvisi / errori del compilatore?

    Ci sono due modi per convertire il tuo codice in modo che il compilatore non si lamenti.

    Uno è quello di utilizzare @objc su ogni funzione o variabile che deve essere esposta al runtime Objective-C:

     @objc func foo() { } 

    L’altro è usare @objcMembers con una dichiarazione di Class . Questo assicura di aggiungere automaticamente @objc a TUTTE le funzioni e le variabili della class. Questo è il modo semplice, ma ha un costo, ad esempio, può aumentare le dimensioni della tua applicazione esponendo le funzioni che non hanno bisogno di essere esposte.

     @objcMembers class Test { } 

    – Cos’è @objc e perché è necessario?

    Se si introducono nuovi metodi o variabili in una class Swift, contrassegnandoli come @objc li espone al runtime Objective-C. Ciò è necessario quando si dispone del codice Objective-C che utilizza la class Swift o, se si utilizzano caratteristiche di tipo Objective-C come i Selectors . Ad esempio, il modello di azione di destinazione: button.addTarget(self, action:#selector(didPressButton), for:.touchUpInside)

    – Perché non dovrei contrassegnare tutto @objc ?

    Ci sono dei negativi che vengono contrassegnati con qualcosa come @objc :

    • Aumento delle dimensioni binarie dell’applicazione
    • Nessuna funzione di sovraccarico

    Tieni presente che si tratta di un riepilogo di alto livello e che è più complicato di quanto abbia scritto. Consiglierei di leggere l’attuale proposta per ulteriori informazioni.

    fonti:

    Migrator non è in grado di identificare tutte le funzioni che richiedono i thunk @objc Inferred Objective-C contrassegnati come deprecati per aiutarti a trovarli
    • Costruisci avvertimenti sui metodi deprecati
    • Messaggi della console durante l’esecuzione di thunk deprecati

    inserisci la descrizione dell'immagine qui

    i miei due centesimi: puoi semplicemente passare a “default” invece di “ON”. Sembra più aderente alla logica Apple.

    (ma tutti gli altri commenti sull’uso di @obj rimangono validi).

    In effetti, ti libererai di questi avvisi disabilitando Swift 3 @objc Inference. Tuttavia, potrebbero apparire piccoli problemi. Ad esempio, KVO smetterà di funzionare. Questo codice ha funzionato perfettamente con Swift 3:

     for (key, value) in jsonDict { if self.value(forKey: key) != nil { self.setValue(value, forKey: key) } } 

    Dopo aver effettuato la migrazione a Swift 4 e aver impostato “Swift 3 @objc Inference” come predefinito, alcune funzionalità del mio progetto hanno smesso di funzionare . Mi ci sono voluti alcuni debug e ricerche per trovare una soluzione per questo. Secondo la mia migliore conoscenza, ecco le opzioni:

    • Abilita “Swift 3 @objc Inference” (funziona solo se hai migrato un progetto esistente da Swift 3) inserisci la descrizione dell'immagine qui
    • Segna i metodi e le proprietà interessati come @objc inserisci la descrizione dell'immagine qui
    • Ritriggers l’inferenza ObjC per l’intera class usando @objcMembers inserisci la descrizione dell'immagine qui

    Riabilitare l’inferenza di @objc ti lascia con gli avvertimenti, ma è la soluzione più rapida. Si noti che è disponibile solo per i progetti migrati da una precedente versione di Swift. Le altre due opzioni sono più noiose e richiedono alcuni scavi per il codice e test approfonditi.

    Vedi anche https://github.com/apple/swift-evolution/blob/master/proposals/0160-objc-inference.md

    Ho ricevuto questo avviso con l’impostazione “Swift 3 @objc Inference” = “Default”. Poi ho capito che è stato impostato per il progetto – non per l’objective. Quindi, assicurati di avere l’impostazione “Predefinita” nel tuo objective per eliminare l’avviso.

    Swift 3 @objc Inference L’uso dell’inferenza di Swift 3 @objc nella modalità Swift 4 è deprecato. Si prega di indirizzare gli avvertimenti di inferenza @objc deprecati, testare il proprio codice con la registrazione “Uso di deprecato Swift 3 @objc inferenza” e quindi disabilitare l’inferenza modificando l’impostazione di build “Swift 3 @objc Inference” su “Default” per “XMLParsingURL” bersaglio.

    arrivato al

    1. Il primo passo ha impostato la configurazione

    2. Cerca in Build Setting Inference

    3. cambia swift 3 @objc Inference Default

    inserisci la descrizione dell’immagine qui

    L’uso dell’inferenza di Swift 3 @objc nella modalità Swift 4 è deprecato?

    usa func call @objc

     func call(){ foo() } @objc func foo() { }