美文网首页
可选链 协议 Self

可选链 协议 Self

作者: 纳兰沫 | 来源:发表于2019-08-20 17:56 被阅读0次

可选链 Optional Chaining

class Car {
    var price = 0
}

class Dog {
    var weight = 0
}

class Person {
    var name: String = ""
    var dog: Dog = Dog()
    var car: Car? = Car()
    func age() -> Int {
        return 18
    }
    
    func eat() {
        print("Person eat")
    }
    subscript(index: Int) -> Int {
        return index
    }
    
}

var person: Person? = Person()
/*
 会先检查person是否为nil
 如果是nil 后面的就不会执行 直接返回nil
 如果不是nil 那就解包 调用
*/
person?.age()
var name = person?.name
var index = person?[6]
- 如果可选项为nil 调用方法 下标 属性失败 结果为nil
- 如果可选项不为nil 调用放法 下标 属性成功 结果会被包装成可选项
- 如果结果本来就是可选项 不会进行再次包装
if let _ = person?.eat(){
    print("eat 调用成功")
}else{
    print("eat 调用失败")
}
var scores = ["jack" : [86,82,84], "Rose" : [79,94,81]]
var array = scores["jack"]
array?[0]
var num1: Int? = 5
//num1加上? 会判断包装里面是否为空 如果不为空 就会继续赋值
num1? = 10// 10

var num2: Int? = nil
//num2为空 就不会继续赋值
num2? = 10//nil
var dict: [String : (Int, Int) -> Int] = [
    "sum" : (+),
    "difference" : (-)
]

var result = dict["sum"]?(10,20)
//dict["sum"]   如果取出来是空的 后面就不会再执行了
print(result)

Optional(30)

协议

协议可以用来定义方法 属性 下标的声明 协议可以被枚举 结构体 类遵守(多个协议之间用,隔开)
- 协议中定义方法时不能有默认参数值
- 默认情况下 协议中定义的内存必须全部都实现

协议中的属性

不要求是存储属性还是计算属性 实现就行
- 协议中定义属性必须是用var关键字
- 实现协议时的属性权限要不小于协议中定义的属性权限
  a.协议定义get set   用var存储属性或者get set计算属性去实现
  b.协议定义get  用任何属性都可以实现
protocol Drawable {
    func draw()
    var x: Int { get set}
    var y: Int { get }
    subscript(index: Int) -> Int{
        get
        set
    }
}

class Person: Drawable {
    var x: Int = 0
    var y: Int = 0
    func draw() {
        print("person draw")
    }
    subscript(index: Int) -> Int{
        get{ return index }
        set{ }
    }
}
protocol Drawable {
    func draw()
    var x: Int { get set}
    var y: Int { get }
    subscript(index: Int) -> Int{
        get
        set
    }
}

class Person: Drawable {
    var x: Int {
        get { return 0 }
        set { }
    }
    var y: Int {
        get { return 0}
    }
    
    func draw() {
        print("person draw")
    }
    subscript(index: Int) -> Int{
        get{ return index }
        set{ }
    }
}

static class

为了保证通用 协议中必须用static定义类型方法 类型属性 类型下标
protocol Drawable {
    static func draw()
}

class Person: Drawable {
    class func draw() {
        <#code#>
    }
}

mutating

只有将协议中的实例方法标记为mutating
  - 才允许结构体 枚举的具体实现修改自身内存
  - 类在实现方法时不用加mutating 
    枚举 结构体才需要加mutating

init

协议中还可以订阅初始化器init
非final类实现时必须加上required

final类不能被继承重写
要求所有遵守这个协议的类都必须有这个初始化器

如果从协议实现的初始化器 刚好是重写了父类的指定初始化器
那么这个初始化器必须同时加required override
protocol Drawable {
    init(age: Int)
}

class Person {
    init(age: Int) {
        
    }
}

class Student: Person, Drawable {
    required override init(age: Int) {
        super.init(age: 0)
    }
}

init init?init!

协议中定义的init? init! 可以用init init?init!去实现
协议中定义的init  可以用init init!去实现
实现方式.png

协议的继承

一个协议可以继承其他协议
protocol Runnable {
    func run()
}

protocol Livable: Runnable {
    func breath()
}

class Person: Livable {
    func run() {
        <#code#>
    }
    
    func breath() {
        
    }
}

协议组合

//接受Person或者其子类的实例
func fn0(obj: Person){}
//接受遵守Livable协议的实例
func fn1(obj: Livable){}
//接受同时遵守Livable Runnable协议的实例
func fn2(obj: Livable & Runnable){}
//接受同时遵守Livable Runnable协议 并且是Person或者其子类的实例
func fn3(obj: Livable & Runnable & Person){}

协议组合 可以包含一个类类型(最多一个)

typealias RealPerson = Livable & Runnable & Person
func fn4(obj: RealPerson){}

CaseIterable

让枚举遵守CaseIterable 协议 可实现遍历枚举值
enum Seasion: CaseIterable {
    case spring, summer,automn,winter
}

let seasions = Seasion.allCases
for seasion in seasions {
    print(seasion)
}

CustomSpringConvertible

遵守CustomSpringConvertible协议 可以自定义实例的打印字符串
class Person: CustomStringConvertible {
    var age: Int
    var name: String
    init(age: Int, name: String) {
        self.age = age
        self.name = name
    }
    var description: String {
        return "age=\(age),name=\(name)"
    }
}

var p = Person(age: 10, name: "Jack")
print(p)

age = 10 name = "Jack"

Any AnyObject

Any        可以代表任何类型(枚举 结构体 类 也包括函数类型)
AnyObject  可以代表任意类类型

如果在协议后面写上AnyObject 代表这个协议只能是类来遵守

var data = [Any]()
data.append(1)
data.append("2")
data.append(23.44)

is as? as! as

is 用来判断是否为某种类型  as用来强制类型转换
protocol Runnable {
    func run()
}

class Person {
    
}

class Student: Person,Runnable {
    func run() {
        print("run")
    }
    func study() {
        print("study")
    }
}

var stu: Any = 10
print(stu is Int)
stu = "Jack"
print(stu is String)
stu = Student()
print(stu is Person)
print(stu is Student)
print(stu is Runnable)

true
true
true
true
true
(stu as? Student)?.study()
没有调用study()
var data = [Any]()
data.append(Int("123") as Any)

X.self X.Type AnyClass

X.self 是一个元类型(metadata)的指针 metadata存放着类型相关信息
X.self属于X.type 类型
var p = Person()
var pType: Person.Type = Person.self
var p = Person()
var pType: Person.Type = Person.self
var stuType: Student.Type = Student.self
pType = Student.self
var perType = type(of: p)

元类型的应用


class Animal {
    required init() {
        
    }
}

class Cat: Animal { }
class Dog: Animal {
    
}
class Pig: Animal {
    
}

func create(_ clses: [Animal.Type]) -> [Animal] {
    var arr = [Animal]()
    for cls in clses {
        arr.append(cls.init())
    }
    return arr
}
print(create([Cat.self,Dog.self,Pig.self]))

[swiftTest.Cat, swiftTest.Dog, swiftTest.Pig]

为了保证子类一定有init 所以 要用required

WeChatcff8b284c6f08183f0b3fdb42590f611.png

Self

Self 一般用作返回值类型 限定返回值跟方法调用者必须是统一类型(也可以作为参数类型)

protocol Runnable {
    func test() -> Self
}

class Person: Runnable {
 
    required init() {}
    func test() -> Self {
        return type(of: self).init()
    }
}

如果Self用在类中 要求返回时调用的初始化器是required 的

相关文章

  • 可选链 协议 Self

    可选链 Optional Chaining 协议 协议中的属性 static class mutating ini...

  • Swift中协议的可选方法的实现判断

      在OC中协议的可选方法是否实现的判断可以通过self.delegate.responseToSelector(...

  • Swift-13.可选类型深入探讨

    本章包含内容: 可选类型深入探讨 可选链的介绍 可选链的返回值 可选链调用下标索引 可选链的赋值操作 基于多层链接...

  • swift 可选协议

    前言 swift 协议 swift可选协议 协议前添加 @objc ,把你想要改成的可选协议前添加 @objc ...

  • 十三、可选链、协议、元类型

    可选链 可选链是一个调用和查询可选属性、方法和下标的过程,它可能为 nil 如果可选项是 nil ,属性、方法或者...

  • 14-Swift可选链、协议

    1.可选链 如果可选项为nil,调用方法、下标、属性失败,结果为nil 如果可选项不为nil,调用方法、下标、属性...

  • iOS-Swift-可选链、协议

    一. 可选链(Optional Chaining) 如果可选项为nil,调用方法、下标、属性失败,结果为nil如果...

  • Swift之[weak self] 和 [unowned sel

    [weak self] 表示 self为可选型 可以为nil 所以在使用的时候必须解包[unowned self]...

  • swift3语法(十三)

    可选链 定义可选链在取值可能为空的属性、方法、下标后面加上 ? 就表示一个可选链在可选值后面加上 ! 来强制展开,...

  • init deinit  可选链 协议 元类型

    swift系列课程 required 不允许同时定义参数标签,参数个数,参数类型相同的可失败初始化器和非可失败初始...

网友评论

      本文标题:可选链 协议 Self

      本文链接:https://www.haomeiwen.com/subject/oqmjsctx.html