Why was UITextField's text property changed to an optional in Swift 2?

后端 未结 4 619
走了就别回头了
走了就别回头了 2020-12-10 00:14

According to the UIKit diff document, in ios9/Swift 2

var text: String! has become var text: String?

According to the documentation

相关标签:
4条回答
  • 2020-12-10 00:56

    In short, (answer to the title) it wasn't.

    In detail:

    To me it makes a lot more sense to have it as an optional that isn't forced unwrapped. Apple is pushing devs to never just use optional! and it only makes sense that they apply the same rules to the API's.

    The reason for this is that it can be nil, and it doesn't make any difference if it is declared with ? or ! for running the code. Using ! actually just removes the warnings in Xcode which are really handy, especially when it comes to API code. If you don't realise it actually is an optional you are just asking for trouble.

    Checking for nil is also much nicer now with guard and you can chain this with a check for "" so it's not really more work.

    In general optionals are better because something that is nil is not using memory. The more optionals we got, the lighter we can make our apps. Also it doesn't even look bad and doesn't add to the pyramid of doom.

    This example will take both strings as arguments, remove the ? in the func parameter and Xcode will be there to warn you.

    I forgot to answer this part directly : It becomes nil when you set it to nil, which you might do to save a little bit of memory. It just doesn't make sense to have the option to set it to nil and not have xcode warn you to handle it properly. => This is impossible...

    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
    

    Update:

    The text property of the UITextfield has a setter that always sets to "" in case of nil, no info on this anywhere in the docs or in the UIKit .h files.

    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 = ""
    
    0 讨论(0)
  • 2020-12-10 01:01

    As Menke mentioned himself, it's actually impossible to set text to nil. Obviously Apple wants it to be documented as nullable, despite the current implementation, and to me it doesn't make any sense - I mean doesn't make enough sense to me. The thing is that it's definitely not "wrong" for Apple to decide that, but is it the elegant way of doing things to everyone? Obviously not. And if you don't agree with them, don't worry, it's totally fine for you to reserve your opinions on some of Apple's decisions.

    So what's the purpose of this change? Maybe they started an internal rule that said never make any properties of UIKits components non-nullable for consistency concern. Maybe they think in theory it's possible for the text property to be released due to memory pressure in some extreme case. Whatever they may be, I don't think they are valid, yet we have to obey. This however doesn't make me a fanboy.

    0 讨论(0)
  • 2020-12-10 01:10

    Also you can use this hack with unicode character:

    extension UITextField {
        var teхt: String { //"х" is U+0445 unicode character
            return self.text ?? ""
        }
    }
    
    0 讨论(0)
  • 2020-12-10 01:11

    A simple way around this problem is to create an extension to UITextField and use that instead of the .text property.

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

    Now you can say textfield.unwrappedText without worrying about optionals. (Of course this is just for reading the value).

    0 讨论(0)
提交回复
热议问题