【iOS】Swift ?和 !(详解)
2015-10-26 14:27
344 查看
Swift语言使用var定义变量,但和别的语言不同,Swift里不会自动给变量赋初始值,
也就是说变量不会有默认值,所以要求使用变量之前必须要对其初始化
。如果在使用变量之前不进行初始化就会报错:
[plain] view
plaincopyprint?
var stringValue : String
//error: variable 'stringValue' used before being initialized
//let hashValue = stringValue.hashValue
// ^
let hashValue = stringValue.hashValue
出错的原因就是在使用stringValue这个变量之前,没有初始化这个变量,也就是这个变量根本就没有得到内存,
这时就会出错。
那么我们可以使用optional类型,后面跟一个?就是了。
[plain] view
plaincopyprint?
// 这就是optional, strValue自动得到默认值:nil
// 这个nil跟Objective-C中的nil不同,不是指针,而是表示值不存在。
var strValue: String?
// 判断optional是否有值
if strValue {
// do what you need to do here
}
文档中有提到说,在使用Optional值的时候需要在具体的操作,比如调用方法、属性、下标索引等前面需要加上一个?,如果是nil值(不存在值),也就是Optional.None,会跳过后面的操作不执行,如果有值,就是Optional.Some可能就会拆包(unwrap),然后对拆包后的值执行后面的操作,来保证执行这个操作的安全性,比如Optional
binding:
[plain] view
plaincopyprint?
// optional binding
// 如果strValue == nil, 那么结果就是nil,不会调用String的hasValue
// 如果strValue != nil, 就返回strValue对应的hashValue值并赋值给常量hashValue
if let hashValue = strValue?.hashValue {
// do something if neccessary
}
在写协议(protocol)时,对于可选代理方法,也需要在调用时在函数名后跟着?,如:
[plain] view
plaincopyprint?
// @objc 是用于处理Swift与OC之间的转换的,由于@optional是OC中的关键字,
// 所以在protocol之前需要添加上@objc。
@objc protocol HttpRequestDelegate {
// @optional 说明这个代理方法是可选方法,
// 那么在调用的时候,需要这样调用:delegate?.requestFinished?(self, downloadData)
// 其中delegate?是因为delegate也是optional的
@optional func requestFinished(request: HttpRequest!, downloadData: NSMutableData!)
// other funcs ...
}
var delegate: HttpRequestDelegate?
var downloadData = NSMutableData()
delegate.requestFinished(self, downloadData)
当然我们也可以使用!来强制拆包,这是我们在保证有值的情况下才会这么用:
[plain] view
plaincopyprint?
var strValue: String?
strValue = "1234"
let integer = strValue!.toInt()
// 更安全的写法是
if strValue {
let integer = strValue!.toInt()
}
隐式强拆包类型:
使用!来声明变量,会成为隐式强拆包可选类型,这表示这个类型永远不会出现nil的情况,但一旦出来,
在调用时就会崩溃。
[plain] view
plaincopyprint?
// Implicitly Unwrapped Optionals
// 使用这种方式声明的话,在调用时不需要使用?或!来说明。
var myLabel: UILabel!
myLabel = UILabel(frame: CGRectMake(10, 100, 300, 10))
myLabel.text = "label"
总结:
通常在什么情况下才会使用optional类型呢?
(1)当我们需要声明这样一个变量,变量在设计初始化函数中没有进行初始化时,就需要声明这个变量为optional类型。因为变量在使用前必须先
声明,并且在设计初始化函数中进行初始化。比如我们在viewDidLoad函数中才进行初始化的控件(类成员),就需要声明为optional且必须是var声明,
因为let声明的常量只能是在初始化函数中进行初始化。
(2)当我们不知道是否会有值的时候,这个变量可以声明为optional,比如代理,我们并没有要求必须传代理过来,那么就需要声明为optional。
(3)作为函数参数时,如果这个参数可以没有值,那么就使用optional类型,比如传代理的时候,通常就是可选的,可以设置为nil
......暂时只想到这些,任何人都可以继续往下补充!
也就是说变量不会有默认值,所以要求使用变量之前必须要对其初始化
。如果在使用变量之前不进行初始化就会报错:
[plain] view
plaincopyprint?
var stringValue : String
//error: variable 'stringValue' used before being initialized
//let hashValue = stringValue.hashValue
// ^
let hashValue = stringValue.hashValue
出错的原因就是在使用stringValue这个变量之前,没有初始化这个变量,也就是这个变量根本就没有得到内存,
这时就会出错。
那么我们可以使用optional类型,后面跟一个?就是了。
[plain] view
plaincopyprint?
// 这就是optional, strValue自动得到默认值:nil
// 这个nil跟Objective-C中的nil不同,不是指针,而是表示值不存在。
var strValue: String?
// 判断optional是否有值
if strValue {
// do what you need to do here
}
文档中有提到说,在使用Optional值的时候需要在具体的操作,比如调用方法、属性、下标索引等前面需要加上一个?,如果是nil值(不存在值),也就是Optional.None,会跳过后面的操作不执行,如果有值,就是Optional.Some可能就会拆包(unwrap),然后对拆包后的值执行后面的操作,来保证执行这个操作的安全性,比如Optional
binding:
[plain] view
plaincopyprint?
// optional binding
// 如果strValue == nil, 那么结果就是nil,不会调用String的hasValue
// 如果strValue != nil, 就返回strValue对应的hashValue值并赋值给常量hashValue
if let hashValue = strValue?.hashValue {
// do something if neccessary
}
在写协议(protocol)时,对于可选代理方法,也需要在调用时在函数名后跟着?,如:
[plain] view
plaincopyprint?
// @objc 是用于处理Swift与OC之间的转换的,由于@optional是OC中的关键字,
// 所以在protocol之前需要添加上@objc。
@objc protocol HttpRequestDelegate {
// @optional 说明这个代理方法是可选方法,
// 那么在调用的时候,需要这样调用:delegate?.requestFinished?(self, downloadData)
// 其中delegate?是因为delegate也是optional的
@optional func requestFinished(request: HttpRequest!, downloadData: NSMutableData!)
// other funcs ...
}
var delegate: HttpRequestDelegate?
var downloadData = NSMutableData()
delegate.requestFinished(self, downloadData)
当然我们也可以使用!来强制拆包,这是我们在保证有值的情况下才会这么用:
[plain] view
plaincopyprint?
var strValue: String?
strValue = "1234"
let integer = strValue!.toInt()
// 更安全的写法是
if strValue {
let integer = strValue!.toInt()
}
隐式强拆包类型:
使用!来声明变量,会成为隐式强拆包可选类型,这表示这个类型永远不会出现nil的情况,但一旦出来,
在调用时就会崩溃。
[plain] view
plaincopyprint?
// Implicitly Unwrapped Optionals
// 使用这种方式声明的话,在调用时不需要使用?或!来说明。
var myLabel: UILabel!
myLabel = UILabel(frame: CGRectMake(10, 100, 300, 10))
myLabel.text = "label"
总结:
通常在什么情况下才会使用optional类型呢?
(1)当我们需要声明这样一个变量,变量在设计初始化函数中没有进行初始化时,就需要声明这个变量为optional类型。因为变量在使用前必须先
声明,并且在设计初始化函数中进行初始化。比如我们在viewDidLoad函数中才进行初始化的控件(类成员),就需要声明为optional且必须是var声明,
因为let声明的常量只能是在初始化函数中进行初始化。
(2)当我们不知道是否会有值的时候,这个变量可以声明为optional,比如代理,我们并没有要求必须传代理过来,那么就需要声明为optional。
(3)作为函数参数时,如果这个参数可以没有值,那么就使用optional类型,比如传代理的时候,通常就是可选的,可以设置为nil
......暂时只想到这些,任何人都可以继续往下补充!
相关文章推荐
- 利用UIWebView打造一个炫酷的视频背景视图(OC & Swift)
- swift 语法 - 以及学习资料
- swift开发笔记14 - 解析json数据文件
- swift学习- 高级操作符(二十四)
- swift:自动引用计数ARC
- 《从零开始学Swift》学习笔记(Day 27)——可选类型
- 《从零开始学Swift》学习笔记(Day 27)——可选类型
- Call can throw, but it is not marked with 'try'
- iOS Swift下dispatch_after的写法
- Swift语言:distance、advance函数更改
- swift中基本转场动画.
- swift:类型转换(is用作判断检测、as用作类型向下转换)
- iOS经典讲解之Swift枚举(Enum)、协议(protocol)、扩展(Extension)
- Swift 学习笔记(三)删除 Main.storyboard 和 LaunchScreen.storyboard
- Swift2.0中解决访问资源库函数 - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error conte错误。
- Swift 的 Currying 特性 | SwiftCafe 咖啡时间
- 关于苹果公司最新的语言Swift
- 初学swift笔记 枚举(七)
- 初学swift笔记 函数(六)
- Swift中ScrollView缩放图片的代理方法