现在只有我开始使用快速语言。我按如下方式初始化按钮
@IBOutlet weak var systemTextButton: UIButton!
之后,我可以使用.setTitle()
属性设置标题。
如果我使用?代替 !初始化然后将.setTitle()
上的错误显示为
UIButton? does not have a member named 'setTitle'
所以,有人请告诉我UIButton之间的区别!和UIButton?
答案 0 :(得分:4)
它们都是可选类型。但是UIButton!
隐含地展开了可选类型。您无需手动打开它。如果您尝试在UIButton!
nil
时访问{{1}}的值,请注意您的应用会崩溃。
欲了解更多信息,请阅读Apple的“The Swift Programming Language”一书中的“Implicitly Unwrapped Optionals”部分。
答案 1 :(得分:2)
该按钮是可选的,因为如果在界面构建器文档中找到该按钮,则不会从头开始确定该按钮。所以要么
也许界面构建器中按钮的存在是某种动态的,然后你可以将它保持为可选(UIButton?
)到允许nil
值。在这种情况下,您必须在使用它之前检查它的存在,或者用myButton!
打开它。您这样做需要您自担风险,因为如果您在nil
值上尝试它,您的程序将崩溃。
答案 2 :(得分:2)
两种变体都在处理选项(变量可能为零)。
@IBOutlet weak var systemTextButton: UIButton!
这是一个隐式解包的可选项。感叹号表示您(程序员)在使用时绝对确定此变量不是nil。您可以通过
设置标题systemTextButton.setTitle(...)
如果此时systemTextButton
为零,则应用程序崩溃。
问号说明此变量可能为零,因此您必须使用:
systemTextButton?.setTitle(...)
现在,setTitle()
仅在systemTextButton
不为零时执行。
希望有所帮助。
有关选项的进一步参考,请参阅The Swift Programming Language
答案 3 :(得分:1)
在这两个例子中,UIButton被声明为可选。 不同之处在于,当您将其声明为UIButton时!它会自动打开,你不必检查它是否为零,你应该确定按钮不会是零。
另一个声明UIButton?不会为您打开此选项,您必须在要访问它(或访问它的属性)时手动执行此操作。 你可以用两种方式做到这一点。如果你确定该对象不是nil,你可以使用它:
button!.setTitle()
但是如果你不确定这个可选项的状态,请使用:
if let btn = button {
btn.setTitle()
}
else {
// button is nil
}
答案 4 :(得分:1)
当你声明UIButton类型的变量?时,你要告诉编译器该变量可能是nil(Objective-C世界中为NULL)。因此,它变为"可选",如果该对象为零,则跳过该对象的所有后续操作。
例如:
class MyClass {
var property: String?
}
let myInstance = MyClass()
if let testVar = myInstance.property {
println("Hello world")
} else {
println("Property unset")
}
您可以在官方swift文档中找到更多信息:
答案 5 :(得分:1)
这些类型的期权被定义为隐式解包的期权。您通过在要使其成为可选的类型之后放置感叹号(String!)而不是问号(String?)来编写隐式展开的可选项。
let possibleString: String? = "An optional string."
let forcedString: String = possibleString! // requires an exclamation mark
let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString // no need for an exclamation mark