简单认识
扩展的作用:为现有的类、结构体、枚举类型、协议添加新功能。与 OC 中的Category类似,不同的是,Swift 的扩展没有名字。关键字extension
如:
extension String {
// 删除空格和换行符 ,返回新字符串
func trimmed() -> String {
self.trimmingCharacters(in: .whitespacesAndNewlines)
}
// 删除空格和换行符(修改自身)
mutating func trim() {
self = self.trimmed()
}
}
如果您要返回一个新值而不是就地更改它,则应该使用诸如
ed或ing的词尾
可以使用扩展向类型添加属性。但有一个规则:它们只能是计算属性,而不是存储属性。原因是添加新的存储属性会影响数据类型的实际大小。
extension String {
var lines: [String] {
self.components(separatedBy: .newlines)
}
}
如果我们在扩展中,实现自定义初始值设定项,那么 Swift将不会禁用自动成员初始值设定项。
extension Book {
init(title: String, pageCount: Int) {
self.title = title
self.pageCount = pageCount
self.readingHours = pageCount / 50
}
}
符合类型可以根据需要,添加自己的sayHello()方法,但如果他们不需要 ,他们始终可以依赖我们的协议扩展中提供的方法。
它还拥有不需要访问被扩展类型源代码就能完成扩展的能力(即逆向建模)
Swift 中的扩展的作用
1、添加计算实例属性、计算类型属性; 2、定义实例方法、类方法; 3、提供新初始化器; 4、定义下标; 5、定义和使用新内嵌类型; 6、使现有的类型遵循某协议 7、扩展现有的协议 8、划分代码区域
- 添加计算实例属性、计算类型属性
extension Double {
var km: Double { return self * 1_000.0 }
var cm: Double { return self / 100.0 }
var mm: Double { return self / 1_000.0 }
var ft: Double { return self / 3.28084 }
}
let oneInch = 25.4.mm
扩展可以添加新的计算属性,但不能添加存储属性,或向现有的属性 添加属性观察者。
- 定义实例方法、类方法
Int类型添加方法repetitions
extension Int {
func repetitions(task: () -> Void) {
for _ in 0..<self {
task()
}
}
}
3.repetitions {
print("Hello!")
}
extension Int {
// 平方
mutating func square() {
self = self * self
}
}
var someInt = 3
someInt.square()
// someInt 现在是 9
- 提供新初始化器
extension UIView {
convenience init(_ ID: String){
super.init()
// ...
}
}
extension Rect {
init(center: Point, size: Size) {
let originX = center.x - (size.width / 2)
let originY = center.y - (size.height / 2)
self.init(origin: Point(x: originX, y: originY), size: size)
}
}
通过扩展提供一个新的构造器,要确保每个通过该构造器创建的实例 都是初始化完整的。
- 定义下标 为已有的类型添加新的下标
extension Int {
subscript(digitIndex: Int) -> Int {
var decimalBase = 1
for _ in 0..<digitIndex {
decimalBase *= 10
}
return (self / decimalBase) % 10
}
}
- 定义和使用新内嵌类型 为已有的类、结构体、枚举类型添加新的内嵌类型
extension Int {
enum Kind {
case negative, zero, positive
}
var kind: Kind {
switch self {
case 0:
return .zero
case let x where x > 0:
return .positive
default:
return .negative
}
}
}
- 使现有的类遵循某协议 如果一个类已经实现了协议的所有要求,但是还没遵守该协议,可以通过扩展来让它遵守这个协议。
protocol TestProtocol {
func test()
}
class TestClass {
func test() {
print("test")
}
}
extension TestClass : TestProtocol {
}
// 使已有的类型遵循一个或多个协议
extension MineController: UITableViewDelegate, UITableViewDataSource {
// implementation of protocol requirements goes here
}
- 扩展协议 1.给一个协议提供默认实现,也间接实现“可选协议”的效果 2.给协议扩充“协议中从未声明过的方法”
protocol TestProtocol {
func test1()
}
extension TestProtocol {
func test1() {
print("TestProtocol test1")
}
func test2() {
print("TestProtocol test2")
}
}
class TestClass : TestProtocol {
}
var cls = TestClass()
cls.test1() // TestProtocol test1
cls.test2() // TestProtocol test2
var cls2: TestProtocol = TestClass()
cls2.test1() // TestProtocol test1
cls2.test2() // TestProtocol test2
- where
// 只给遵守myProtocol协议的UIView添加了拓展
// 强大的协议拓展 可以给协议添加默认实现 面向协议编程的基础
extension HomeHeaderViewDelegate where Self: UIView {
}