为什么UITextField的文本属性在Swift 2中更改为可选?

Wil*_*ill 43 uitextfield uikit ios swift swift2

根据UIKit diff文档,在ios9/Swift 2中

var text: String! 已经成为 var text: String?

根据UITextField文档,它特别说

This string is @"" by default.

我不明白这种改变的目的.如果文本字段完全存在,那么该属性是否应始终为空字符串?该字段在什么时候返回一个空字符串?一旦用户与之交互?一旦它被添加到视图层次结构中?它在什么时候返回nil

如果文本字段首先存在,是否始终可以假设文本属性也存在?这似乎只是它会导致大量的查找/替换.text.text!

我没有看到文档中提到它的位置,所以也许有人有一些背景故事或帮助解释为什么会改变.

R M*_*nke 16

简而言之,(回答标题)事实并非如此.

详细地:

对我来说,将它作为一个不被强制解包的可选项更有意义.Apple正在推动开发人员不要只使用optional!它,只有他们将相同的规则应用于API才有意义.

这样做的原因是它可以是nil,如果声明为?!运行代码它没有任何区别.使用!实际上只是删除Xcode中的警告,这非常方便,特别是在API代码方面.如果您没有意识到它实际上是可选的,那么您只是在寻找麻烦.

现在检查nil也好多了guard,你可以用支票链接这个,""所以它不是更多的工作.

通常选项更好,因为nil不使用内存.我们获得的选项越多,我们的应用程序就越轻.它甚至看起来都不好看,并没有添加到厄运的金字塔中.

这个例子将两个字符串作为参数,删除?func参数,Xcode将在那里警告你.

我忘了直接回答这个部分: 当你将它设置为nil时它变为nil,你可能会这样做以节省一点内存.选择将其设置为nil并没有让xcode警告你正确处理它是没有意义的.=>这是不可能的......

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
Run Code Online (Sandbox Code Playgroud)

更新:

的文本属性UITextfield具有一个setter总是设置为""在以下情况下nil,在该文档或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 = ""
Run Code Online (Sandbox Code Playgroud)

  • 我认为你没有在这里解析我的问题。我绝对理解可选项的价值。我特别询问了`UITextField`,它是`text:String` 属性。在 iOS 9 中,它是可选的,而在此之前它不是,并且文档仍然说它 ** 始终** 是一个空字符串。测试操场证实了这一点。我想知道为什么改变了这个,或者是否有一些用例使这变得有价值。 (10认同)
  • @NicolasMiari对于你​​的情况,这应该没问题,因为它听起来像你正在使用字符串.但是,如果你强制打开一个UITextField然后立即尝试将其转换为int,例如`Int(textField.text!)`你将得到`nil`而不是空字符串.在这种情况下,我建议使用类似`if let number = Int(textField.text!){...}`. (3认同)
  • 如果它永远不会变成零,那么强制解包是否安全?我正在尝试从“UITextField”获取文本,如果它是空字符串,则使用占位符。向此逻辑添加可选的检查/展开使其非常具有挑战性...... (2认同)

sgi*_*gib 7

解决此问题的一种简单方法是创建UITextField的扩展并使用它而不是.text属性.

extension UITextField {
    var unwrappedText: String {
        return self.text ?? ""
     }
}
Run Code Online (Sandbox Code Playgroud)

现在你可以说textfield.unwrappedText而不用担心选项.(当然这只是为了阅读价值).


sup*_*org 5

正如Menke自己提到的,实际上不可能设置text为nil。显然苹果希望它被记录为可为空,尽管目前的实现,对我来说它没有任何意义 - 我的意思是对我来说没有足够的意义。问题是,苹果的决定绝对没有“错误”,但这是对每个人做事的优雅方式吗?很明显不是。如果你不同意他们的观点,不用担心,你对苹果的一些决定保留意见是完全可以的。

那么这个改变的目的是什么呢?也许他们制定了一条内部规则,表示出于一致性考虑,永远不要使 UIKit 组件的任何属性不可为空。也许他们认为理论上在某些极端情况下文本属性可能会由于内存压力而被释放。不管它们是什么,我认为它们都是无效的,但我们必须服从。然而,这并不能让我成为粉丝。