2014-06-30 10 views
15

Voglio ottenere il nome del metodo corrente da utilizzare in un messaggio in formato simile a questoQual è l'equivalente swift di _cmd?

[NSExeception raise:NSInternalInconsistencyException format:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)] 

Inoltre, voglio usare _cmd per impostare oggetto associato. Apprezzo qualsiasi idea.

+4

[ '__FUNCTION__'] (https://developer.apple.com/library/prerelease/ios/documentation/swift/conceptual/swift_programming_language/Expressions.html#//apple_ref/doc/uid/ TP40014097-CH32-XID_691) –

+1

Come questa domanda è duplicata? –

+0

Questo è un dup di http://stackoverflow.com/questions/24483379/cmd-in-swift-language –

risposta

0

Non esiste un equivalente Swift di _cmd. Ci sono pochi motivi per usarlo in Swift.

Considerare _cmd in Objective-C. Quando è utile? Nella maggior parte dei casi, il valore di _cmd corrisponde al nome del metodo in cui si trova il codice, quindi è già noto in fase di compilazione e non è necessario un valore di runtime. Ecco alcuni casi possibili quando _cmd è utile in Objective-C:

  • In una macro. La macro viene espansa nel codice, quindi se _cmd viene visualizzata nella macro, viene inserita nell'origine in cui viene utilizzata, quindi il nome del metodo può essere utilizzato all'interno della macro. Tuttavia, tali macro non esistono in Swift. Le macro Plus sono in fase di compilazione, quindi un meccanismo di compilazione come __FUNCTION__ funzionerebbe allo stesso modo.
  • È possibile definire una funzione C che prende self e _cmd e utilizzarlo (la stessa funzione) come l'attuazione di diversi metodi, aggiungendolo utilizzando class_addMethod e class_replaceMethod, e il _cmd all'interno della funzione sarà aiutare a distinguere tra i diversi chiamate di metodo. Tuttavia, class_addMethod e class_replaceMethod non sono disponibili in Swift.
  • Il metodo di swizzling è anche un processo che mette in crisi l'implementazione di un metodo. Poiché in swizzling si scambiano le implementazioni di due metodi, _cmd consente di rivelare il nome effettivo del metodo utilizzato nella chiamata, che potrebbe non corrispondere al metodo in cui si trova il codice nel codice sorgente, dal momento che le implementazioni vengono scambiate. Immagino che il metodo swizzling possa essere ancora possibile in Swift, dal momento che method_exchangeImplementations è ancora disponibile in Swift. Ma nel metodo di swizzling, il metodo di swap è adattato al metodo con cui si sta scambiando, quindi se viene chiamato, non c'è ambiguità sul nome del metodo che viene chiamato.
  • Nel caso in cui si ottenga manualmente lo IMP (funzione di implementazione) di un metodo e lo si chiami manualmente con un altro selettore. In questo caso, l'interno della funzione può vedere il diverso selettore in _cmd. Tuttavia, non devi preoccuparti di ciò in Swift perché i metodi che ottengono il IMP non sono disponibili.
+0

Swizzling dovrebbe essere un'ultima soluzione di emergenza per i bug del framework. Detto questo, ecco un post sul tempo di esecuzione di Swift di ** NSHipster ** [swizzling in Swift] (http://nshipster.com/swift-objc-runtime/) –

+0

Mi permetto di dissentire. Descrittori di ordinamento. Mi piace usare il nome accessor di un metodo, in modo che se il nome dell'attributo cambia, il compilatore si lamenta. – horseshoe7

+0

A parte lo swizzling, una ragione potrebbe essere quella di ignorare un selettore di protocollo opzionale in modo più pulito. Se super.responds (a: _cmd) sarebbe un miglioramento netto. – xtravar

31
NSStringFromSelector(_cmd); // Objective-C 

print(__FUNCTION__) // Swift 2 

print(#function) // Swift 3 
+8

questa dovrebbe essere la risposta accettata – phlebotinum

+2

"__FUNCTION__" sarà deprecato e verrà rimosso da Swift 3, quindi, utilizzare invece: #function –

+2

Identificatori di debug esatti come '__FILE__',' __LINE__', '__COLUMN__' e' __FUNCTION__ 'sono stati sostituiti da' # file', '# line',' # column' e '# function' in ** Swift 2.2 **. – cherrmanncom

Problemi correlati