Swift3.0 - 探究Self的用途

Swift3.0 - 真的很简单
Swift3.0 - 数据类型
Swift3.0 - Array
Swift3.0 - 字典
Swift3.0 - 可选值
Swift3.0 - 集合
Swift3.0 - 流控制
Swift3.0 - 对象和类
Swift3.0 - 属性
Swift3.0 - 函数和闭包
Swift3.0 - 初始化和释放
Swift3.0 - 协议protocol
Swift3.0 - 类和结构体的区别
Swift3.0 - 枚举
Swift3.0 - 扩展
Swift3.0 - 下标
Swift3.0 - 泛型
Swift3.0 - 异常错误
Swift3.0 - 断言
Swift3.0 - 自动引用计数(strong,weak,unowned)
Swift3.0 - 检测API
Swift3.0 - 对象的标识
Swift3.0 - 注释
Swift3.0 - 元类型
Swift3.0 - 空间命名
Swift3.0 - 对象判等
Swift3.0 - 探究Self的用途
Swift3.0 - 类簇
Swift3.0 - 动态调用对象(实例)方法
Swift3.0 - 文本输出
Swift3.0 - 黑魔法swizzle
Swift3.0 - 镜像
Swift3.0 - 遇到的坑

  • 如何实现对象拷贝

第一种方法:

1.遵守协议 NSCopying
2.实现协议

NSCopying 协议

public protocol NSCopying {
    public func copy(with zone: NSZone? = nil) -> Any
}

示例代码:

class Student:NSCopying {
    var name: String
    required init(name:String){
        self.name = name
    }
    func copy(with zone: NSZone? = nil) -> Any {
        let student = Student(name: self.name)
        return student
    }
}
 // 使用
 let student1 = Student(name: "XUJIE")
let student2:Student = student1.copy() as! Student
student2.name = "酷走天涯"
print(student1.name)
print(student2.name)

运行:

XUJIE
酷走天涯

分析:

由于NSCopying 协议里面的方法copy 返回的值为Any 系统没法推断出来是Student 类型,所以必须 as! 指明是Student 类型 过程有点繁琐

  • 第二种方法

1.创建一个一个required 修饰的初始化方法
2.自定义一个copy方法

示例代码

class Student{
    var name: String
    required init(name:String){
        self.name = name
    }
    func copy() -> Self {
       let result = type(of: self).init(name:self.name)
       return result
    }
}
// 使用
let student1 = Student(name: "XUJIE")
let student2 = student1.copy()
student2.name = "酷走天涯"
print(student1.name)
print(student2.name)

运行结果:

XUJIE
酷走天涯

分析:

type(of: self) 获取到自身类的类型,然后通过init(name:self.name) 初始化一个对象 ,初始化的对象为Self 类型

思考:初始化为什么要使用required 修饰的的初始化

参考元类型

设计规范:

像拷贝这种行为, 不是很多对象都具有的行为,我们应该把它设计成协议,让类去继承它

protocol Copy{
    func copy() -> Self
}

其实如果我们但从技术上实现, 下面的方式也可以的

    func copy() -> Student{
       let result = Student.self.init(name:self.name)
       return result
    } 

   func copy() -> Student{
       let result = Student.init(name: self.name)
       return result
    }

    func copy() -> Student{
       let result = Student(name: self.name)
       return result
   }
  • 给多个对象扩展相同的方法

需求: 给数字扩展一个返回平方的操作

// 定义个协议
protocol NumberProtocol{
}
// 扩展实现协议
extension Int:NumberProtocol{
}
extension Double:NumberProtocol{
}
// 给协议扩展方法
extension NumberProtocol{
// 我们不确定返回的Self 到底是什么类型
func squareValue()-> Self{
if self is Int{
    let n = self as! Int
    return n * n as! Self
}
if self is Double{
    let n = self as! Double
    return n * n as! Self
}
return 0 as! Self
}
}
print(3.44.squareValue())
print(3.squareValue())

如果您有更多思路,请交流探讨。

推荐阅读更多精彩内容