在Objective-C
中,init 方法
除了返回 self
以外,其实和一个普通的实例方法
并没有
太大的区别
。如果你喜欢的话,甚至可以多次
进行调用
,这都没有限制。一般来说,我们还会在初始化失败
(比如输入不满足要求无法正确的初始化)的时候返回nil
来通知调用者这次初始化没有
正确完成
。
但是,在Swift中默认情况
下初始化方法
是不能
写return
语句来返回值的,也就是说我们没有
机会初始化
一个Optional
的值。一个很典型的例子就是初始化
一个 url
。在Objective-C
中。如果我们使用一个错误的字符串
来初始化一个NSURL 对象
,返回会是nil
,代表初始化失败
。所以下面这种“防止百度吞链接”式的字符串(注意两个t
之间的空格和中文式句号),也是可以正常编译和运行的,只是结果是个nil
NSURL *url = [NSURL URLWithString:@"ht tp://swifter。tips"];
NSLog(@"%@", url); // nil
-initWithString:
在Swift中对应的是一个convenience init
方法:public convenience init?(string URLString: String)
。上面的Objective-C代码在Swift中等效为:
let url1 = NSURL.init(string: "ht tp://swifter。tips")
let url2 = URL.init(string: "ht tp://swifter。tips")
print(url1) // nil
print(url2) // nil
虽然在默认
情况下不能
在init
中返回nil
,但是我们可以在init声明
时在其后加
上一个 ?
或者!
来表示初始化失败时可能
返回nil
。比如为Int
添加一个extension
来让其可以接收字符串
,并通过字符串初始化
对应的数字时,就可能遇到初始化失败的情况,Int
本身有@inlinable public init?(_ description: String)
初始化方法,我们只是做个实验:
extension Int {
init?(fromString: String) {
let i: Int? = (fromString as NSString).integerValue
if fromString.count > 0 && i ?? 0 > 0 {
self = i!
} else {
return nil
}
}
}
let number = Int.init(fromString: "12")
let number2 = Int.init(fromString: "十二")
print(number)
print(number2)
number
和number2
都将是Int? 类型
,通过Optional Binding
,我们就能知道初始化
是否成功,并安全的使用它们了。我们在这类初始化方法中还可以对self
进行赋值
,也算是init 方法
里的特权
之一。