Il Swift documentation dice il seguente circa protocolli:: Perché @ObjC è necessario per il controllo di conformità e i requisiti facoltativi?
È possibile verificare la conformità del protocollo solo se il protocollo è contrassegnato con l'attributo @objc, come si è visto per il protocollo HasArea sopra. Questo attributo indica che il protocollo deve essere esposto al codice Objective-C ed è descritto in Uso di Swift con Cocoa e Objective-C. Anche se non si interagisce con Objective-C, è necessario contrassegnare i protocolli con l'attributo @objc se si desidera poter verificare la conformità del protocollo .
Si noti inoltre che i protocolli @objc possono essere adottati solo dalle classi e non da da strutture o enumerazioni. Se si contrassegna il protocollo come @objc in per verificare la conformità, sarà possibile applicare il protocollo solo ai tipi di classe.
e
requisiti del protocollo opzionali possono essere specificati solo se il protocollo è contrassegnato con l'attributo @objc. Anche se non si sta interoperando concon Objective-C, è necessario contrassegnare i protocolli con l'attributo @objc se si desidera specificare i requisiti facoltativi.
Si noti inoltre che i protocolli @objc possono essere adottati solo dalle classi e non da da strutture o enumerazioni. Se si contrassegna il protocollo come @objc nell'ordine per specificare i requisiti facoltativi, sarà possibile applicare il protocollo a tipi di classe.
Perché non puri protocolli Swift (non @objc
) essere controllati per la conformità. Perché non hanno requisiti opzionali? Qualcuno può indovinare il motivo di progettazione linguistica sottostante?
mi aspetto che a un certo (probabilmente lontano) tempo indeterminato nel futuro di Apple lentamente reimplementare e sostituire cacao e Cocoa Touch con le librerie programmati esclusivamente a Swift. A quel tempo, se non dovessimo evitare l'uso di materiale Obj-C, dovremmo evitare di utilizzare i requisiti del protocollo opzionali e la conformità ai controlli del protocollo nel nostro codice?
Se sì, qual è il modo idiomatico di Swift per ottenere modelli simili senza utilizzare @objc
? (. Ad esempio, un delegato con metodi opzionali)
Ad esempio, questo semplice caso d'uso non può essere implementato con @objc
protocolli non (e Printable
, DebugPrintable
e Streamable
sono non @objc
:
import UIKit
let firstName = "John"
let lastName = "Appleseed"
let age = 33
let height = 1.74
let values: [Any] = [firstName, lastName, age, height]
let stringifiedValues = [String]()
for value in values
{
if let pritanbleValue = value as? Printable
{
stringifiedValues.append(value.description)
}
else if let debugPrintableValue = value as? DebugPrintable
{
stringifiedValues.append(value.debugDescription)
}
else if let streamableValue = value as? Streamable
{
var string = ""
streamableValue.writeTo(&string)
stringifiedValues.append(string)
}
// etc.
else
{
stringifiedValues.append("[NoStringRepresentation]")
}
}
Grazie per la risposta premurosa! Tuttavia, non sono d'accordo con il secondo paragrafo. Come può un delegatore verificare i singoli metodi del suo delegato a meno che non disponga dei requisiti opzionali del protocollo? Il terzo paragrafo non funziona per me, sto chiedendo del puro codice Swift in un ipotetico codice senza ObjC. Una possibilità che posso pensare è che questa è solo una caratteristica mancante al momento e sarà aggiunta in seguito. –
@ RicardoSánchez-Sáez: In realtà, nessun APA Cocoa verifica mai la conformità del protocollo; controllano sempre che l'oggetto risponda al particolare selettore inviato. È facile farlo in Objective-C. In Swift, devi solo lanciarlo su 'AnyObject' per poter usare il concatenamento opzionale o testare il metodo opzionale. (Naturalmente, se non sei sicuro che l'oggetto sia un'istanza del protocollo, probabilmente è già 'AnyObject'.) – newacct
Hai ragione, forse il pattern delegato non era un buon esempio. Tuttavia, ritengo che il controllo della conformità del protocollo sia ancora utile. Vedere l'esempio che ho aggiunto alla domanda. Non è possibile utilizzare il concatenamento opzionale per metodi sconosciuti su AnyObject senza utilizzare selettori (ei selettori non hanno posto in puro Swift). –