在swift 开发过程中,尤其是第三方库中,我们经常可以看到Self
,但是Self
与self
,它们两个是不一样的,下面我们通过示例来对比下两者的区别。
相信大家都知道self
这个关键字的具体作用,它跟OC里的self
基本一样,但是Self
关键字只能用在类里, 作为函数返回值类型, 表示当前类,限定返回值跟方法调用者必须是同一类型,在定义协议的时候Self
用的频率很高,而且当你用错Self
的时候编译器会这样提示
'Self' is only available in a protocol or as the result of a method in a class
例1:Self
关键字用在类里, 作为函数返回值类型, 表示当前类。
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let objA = TestClass(a: 1, b: 2)
objA.testA(param: 3)
objA.testB(param: 4)
print("a:\(objA.a),b:\(objA.b)")
}
}
class TestClass {
var a: Int
var b: Int
init(a: Int, b: Int) {
self.a = a
self.b = b
}
@discardableResult
func testA(param: Int) -> Self {
self.a = param
return self
}
@discardableResult
func testB(param: Int) -> TestClass {
self.b = param
return self
}
}
小结:
这段代码里有self和Self, self指向类自身;Self只能作为函数关键字, testA和testB函数的返回值是TestClass类型,这里 TestClass 和 Self 等价。这里的返回值TestClass和OC中instancetype,有点异曲同工之处。
例2:Self
在协议中的使用场景
protocol SomeProtocol {
func test() -> Self
}
class Person : SomeProtocol {
required init() {}
func test() -> Self {
type(of: self).init()
}
}
小结:
Self可以用于协议(protocol)中限制相关的类型,比如SomeProtocol协议中 func test() -> Self
方法中返回Self
,也就是说Person类继承了SomeProtocol协议必须返回Self(返回值必须是Person类型)。
image.png
注意:
1.test() 方法中不能直接返回Person(),否则会报类型不匹配错误;
原因: 主要是考虑,如果实现这个协议的类,有子类,即也就是有继承关系,那么直接返回父类将会报错,因为我们肯定希望调用子类就返回子类。
image.png
所以,考虑到上述继承的场景,我们期望返回的必然是当前对象类,需要通过type(of: self)
获取当前对象,然后再调用初始化方法即可。
正确的写法如下所示:
image.png
网友评论