当我进行可选链接时,为什么会出现错误?

问题描述:

protocol textingprotocol : class { 
    func didEnterText (text:String) 
} 

class secondViewController: UIViewController {  
weak var delegate:textingprotocol? 

@IBOutlet weak var txtField: UITextField? 

@IBAction func dismissButton(sender: UIButton) { 

    delegate!.didEnterText(txtField?.text) // A: doesn't work 
    delegate!.didEnterText(txtField?.text!) // B: doesn't work 
    delegate!.didEnterText((txtField?.text)!) // C: works 

} 

答:我没有在做可选链和行只会工作,如果文本有一个值,如果没有那么它会优雅地失败? 但它给出:当我进行可选链接时,为什么会出现错误?

可选类型'String?'的值不打开;你的意思是使用 '!'要么 '?'?

B:即使当我给出的编译器错误的上面,还有我解开它,它仍然是不满意它希望它像C.我的理解与?我已经解开txtField并与!我已解开文字,仍然困惑为什么它不起作用

为什么C工作,但不是B?没有比C线更清洁的方式吗? C线看起来很不吸引人。

+1

应该是'@IBOutlet弱VAR txtField:'的UITextField –

+0

@LeoDabus哈!谢谢。但看着“文本”属性。为什么这是可选的?我的意思是为什么我Cmmd +单击它它显示'@属性(非原子,只读)NSString *文本;'它不显示任何像'文本:字符串?'它是如何从Objective-C翻译为可选? – Honey

+0

我不是swift专家,所以我会留下一条评论而不是答案......'didEnterText'需要一个非零值,所以我的理解是,如果'txtField'没有'.text '声明的一部分甚至不会被评估,因此添加'.text!'不能解决无文本字段的问题。在选项C中,编译器看到的所有值都是“保证”为非零值,因为整个事物被包装在parens中... – Mike

didEnterText不需要String?。它需要String。因此,你不能使用带有问号的简单可选链来获得它的参数。您必须实际上解开为String,而不是暂时解开为String? - 或 - 无。

现在,txtField是一个可选的,所以你需要解开它。

而UITextField的text属性是可选的,所以你也需要解开它。

所以最简单的方法是解开他们两个,绝对:

delegate!.didEnterText(txtField!.text!) 

如果你不希望这样做(因为你害怕他们中的一个将是零和崩溃的应用程序),你将保护整个事情与if let

if let s = txtField?.text { 
     delegate!.didEnterText(s) 
    } 
+0

所以基本上你说的非选择性将永远不会使用可选项,除非它通过'!',即不是'''保证? – Honey

+0

我不太清楚你的意思。一个简单的事实是,你不能提供一个'String'来预期'String'。 'String'隐藏在'String?'里面。你必须打开它!你可以用'!'不安全地拆开它,或者用'if let'安全地有条件地拆开它,但是在你使用它之前你必须拆开它。 – matt

+1

它几乎看起来好像你不完全清楚什么是可选_is_。如果是这样的话,我的书会帮助你:http://www.apeth.com/swiftBook/ch03.html#_optional – matt