闽公网安备 35020302035485号
class Person {
var name: String
// 堆代码 duidaima.com
init(name: String) {
// 这里的 self.name 指的是实例属性
// 而 name 是传入的参数
self.name = name
}
func introduce() {
print("大家好,我叫 \(self.name)")
// 其实这里的 self 可以省略
print("大家好,我叫 \(name)")
}
}
let xiaoming = Person(name: "小明")
xiaoming.introduce()
什么时候必须用 self 呢?主要是这两种情况:struct Point {
var x: Double
var y: Double
mutating func move(x: Double, y: Double) {
// 必须用 self 来区分属性和参数
self.x += x
self.y += y
}
}
2. 在闭包中引用实例属性时class ViewController {
var count = 0
func setupTimer() {
Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in
// 闭包中必须显式使用 self
self.count += 1
print("计数: \(self.count)")
}
}
}
Self:类型的占位符protocol Duplicatable {
// Self 表示遵循协议的具体类型
func duplicate() -> Self
}
class Document: Duplicatable {
var content: String
init(content: String) {
self.content = content
}
// 这里返回的是 Document 类型
func duplicate() -> Self {
// 需要用 type(of:) 来创建相同类型的实例
return type(of: self).init(content: self.content)
}
requiredinit(content: String) {
self.content = content
}
}
Self 的妙处在于它的多态性。不同的类型遵循同一个协议时,Self 会自动变成对应地类型:class PDFDocument: Document {
// duplicate() 返回的是 PDFDocument,不是 Document
}
class WordDocument: Document {
// duplicate() 返回的是 WordDocument,不是 Document
}
Self.self:类型的元类型protocol Registrable {
staticfunc register()
}
extension Registrable {
staticfunc register() {
// Self.self 获取的是具体类型的元类型
print("正在注册 \(Self.self)")
}
}
class UserService: Registrable {}
class PaymentService: Registrable {}
// 调用静态方法
UserService.register() // 打印: 正在注册 UserService
PaymentService.register() // 打印: 正在注册 PaymentService
在实际开发中,Self.self 经常用在需要传递类型信息的场景:// 泛型函数,需要知道具体类型
func createInstance<T: Decodable>(of type: T.Type, from json: String) -> T? {
// 使用传入的类型信息来解码 JSON
let data = json.data(using: .utf8)!
returntry? JSONDecoder().decode(type, from: data)
}
// 在协议扩展中使用
protocol JSONDecodable: Decodable {
staticfunc decode(from json: String) -> Self?
}
extension JSONDecodable {
staticfunc decode(from json: String) -> Self? {
// 这里的 Self.self 就是调用者的具体类型
return createInstance(of: Self.self, from: json)
}
}
实战技巧:什么时候用哪个?.需要把类型作为参数传递
class Animal {
// ❌ 错误:class 中不能直接返回 Self
// func clone() -> Self { ... }
// ✅ 正确:需要用 required init
func clone() -> Self {
return type(of: self).init()
}
required init() {}
}
2. 忘记 weak selfclass ViewController {
func loadData() {
APIClient.request { data in
// ❌ 可能造成循环引用
self.updateUI(with: data)
// ✅ 使用 weak self
// [weak self] in
// self?.updateUI(with: data)
}
}
}
3. Self 和具体类型名混用protocol Comparable {
// ❌ 不够灵活
func isEqual(to other: MyClass) -> Bool
// ✅ 使用 Self 更通用
func isEqual(to other: Self) -> Bool
}