2015-09-17 9 views
41

Secondo il UIKit diff document, in ios9/Swift 2Perché la proprietà di testo di UITextField è stata modificata in un'opzione in Swift 2?

var text: String! è diventato var text: String?

Secondo il documentation for UITextField si dice specficially

This string is @"" by default.

non capisco lo scopo di questo cambiamento . Non dovrebbe questa proprietà essere sempre una stringa vuota se il campo di testo esiste? A che punto questo campo restituisce una stringa vuota? Una volta che l'utente interagisce con esso? Una volta che è stato aggiunto alla gerarchia della vista? A che punto restituisce nil?

Se il campo di testo esiste in primo luogo, è sempre sicuro assumere anche la proprietà di testo? Sembra che porti molto a trovare/sostituire .text a .text!

Non vedo dove viene menzionato nei documenti, quindi forse qualcuno ha qualche retroscena o aiuto sul perché è cambiato.

+0

Per ulteriori dettagli, ho solo l'installazione di un parco giochi e ha fatto un UITextField. La proprietà text è infatti istantaneamente una stringa vuota * opzionale *. Ora sono più confuso – Will

+1

Sembra che Apple non si fidi della loro API per darci sempre un valore non nullo per la proprietà text, quindi trasferiscono la responsabilità di 'guard' a noi. Non un fan di questo approccio. – teradyl

risposta

16

In breve, (risposta al titolo) non lo era.

In dettaglio:

A me fa molto più senso di avere come un optional che non è costretto da scartare. Apple sta spingendo gli sviluppatori a non usare mai solo optional! e ha senso solo che applichino le stesse regole alle API.

Il motivo è che può essere nullo e non fa alcuna differenza se è dichiarato con ? o ! per l'esecuzione del codice. L'utilizzo di ! rimuove di fatto gli avvisi in Xcode, che sono davvero utili, specialmente quando si tratta di codice API. Se non ti rendi conto che in realtà è un optional, stai solo chiedendo dei problemi.

Il controllo di nil è ora molto più bello con guard e puoi concatenarlo con un assegno per "" quindi non è più un lavoro.

In generale le opzioni sono migliori perché qualcosa che è nullo non utilizza la memoria. Più opzioni abbiamo, più leggero possiamo fare le nostre app. Inoltre non sembra nemmeno male e non aggiunge alla piramide del destino.

Questo esempio prenderà entrambe le stringhe come argomenti, rimuovere ? nel parametro func e Xcode sarà lì per avvisare.

Ho dimenticato di rispondere a questa parte direttamente: Essa diventa nullo quando lo si imposta a zero, il che si potrebbe fare per risparmiare un po 'di memoria. Non ha senso avere l'opzione di impostarlo su zero e non avere xcode ti avverta di gestirlo correttamente. => Questo è impossibile ...

var forcedUnwrappedString : String! = "" 
var optionalString : String? = "" 

forcedUnwrappedString = nil 
optionalString = nil 

func doSomethingWithString(string : String?) -> String? { 
    guard var unwrappedString = string else { 
     // error handling here 
     return nil 
    } 
    let tempString = unwrappedString + "!" 

    return tempString 
} 

func doSomethingUnsafeWithString(string : String) -> String { 

    let tempString = string 
    return tempString 

} 

var newString = doSomethingWithString(optionalString) 
var newString2 = doSomethingWithString(forcedUnwrappedString) 

newString = doSomethingUnsafeWithString(optionalString!) // this will crash without a warning fro xcode 
newString2 = doSomethingUnsafeWithString(forcedUnwrappedString) // this will crash without a warning fro xcode 

Aggiornamento:

La proprietà testo della UITextfield ha un setter che imposta sempre a "" in caso di nil, nessuna informazione su questo articolo ovunque nella documentazione o in file della UIKit .h.

var textField = UITextField(frame: CGRect(x: 0, y: 0, width: 0, height: 0)) 
var string = textField.text // string = "" 
textField.text = nil 
string = textField.text // string = "" 
+10

Non penso che tu abbia analizzato la mia domanda qui. Capisco perfettamente il valore degli optionals. Sto specificatamente chiedendo di "UITextField' ed è la proprietà' text: String'. In iOS 9 è stato reso opzionale, mentre prima non lo era, e la documentazione dice ancora che ** ** sarà sempre una stringa vuota. Testare il campo da gioco lo conferma. Mi chiedo perché questo è stato cambiato o se c'è qualche caso d'uso che lo rende prezioso. – Will

+0

Ho letto tutta la tua domanda, inoltre non mi sono preoccupato di spiegare quali sono gli optionals. Ho spiegato perché Apple lo ha cambiato da un facoltativo scartato forzato a uno che non è perché la tua domanda afferma che era un opzionale scartato forzato prima ed è un normale in Swift2. Ora nel tuo commento dichiari che non era un optional prima? –

+0

Appena controllato, era un opzionale facoltativo da scartare prima, quindi è possibile impostarlo su zero. Ma xcode non ti avviserà di questo. –

4

Come Menke si è detto, in realtà è impossibile impostare text a zero. Ovviamente Apple vuole che sia documentato come nullable, nonostante l'attuale implementazione, e per me non ha alcun senso - voglio dire non ha senso per me. Il fatto è che non è sicuramente "sbagliato" per Apple decidere, ma è il modo elegante di fare le cose a tutti? Ovviamente no. E se non sei d'accordo con loro, non ti preoccupare, è assolutamente bene per te riservare le tue opinioni su alcune delle decisioni di Apple.

Quindi qual è lo scopo di questo cambiamento? Forse hanno iniziato una regola interna che diceva non rendere mai nulla le proprietà dei componenti di UIKits non annullabili per motivi di coerenza. Forse pensano che in teoria sia possibile rilasciare la proprietà del testo a causa della pressione della memoria in alcuni casi estremi. Qualunque cosa possano essere, non penso che siano validi, ma dobbiamo obbedire. Questo però non mi rende un fan.

7

Un modo semplice per risolvere questo problema è creare un'estensione a UITextField e utilizzarla al posto della proprietà .text.

extension UITextField { 
    var unwrappedText: String { 
     return self.text ?? "" 
    } 
} 

Ora si può dire textfield.unwrappedText senza preoccuparsi di optional. (Ovviamente questo è solo per leggere il valore).

-2

Inoltre è possibile utilizzare questo hack con carattere Unicode:

extension UITextField { 
    var teхt: String { //"х" is U+0445 unicode character 
     return self.text ?? "" 
    } 
} 
+0

Questo può "funzionare" ma certamente non è un'idea "buona". E non è utile rispondere a questa domanda di "Perché è stata modificata l'API" – JMFR