Swift 协议 protocol 小结

在Swift 2发布时,苹果将Swift定义为一门面向协议编程的语言,协议在Swift中被赋予了更加强大、灵活的功能。相比于Objective-C的协议,Swift的协议不仅可以被用做代理,也可以用作对接口的抽象,代码的复用。

1、面向协议编程

---依赖倒置原则:告诉我们要面向接口编程


定义:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。

问题由来:类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码来达成。这种场景下,类A一般是高层模块,负责复杂的业务逻辑;类B和类C是低层模块,负责基本的原子操作;假如修改类A,会给程序带来不必要的风险。

解决方案:将类A修改为依赖接口I,类B和类C各自实现接口I,类A通过接口I间接与类B或者类C发生联系,则会大大降低修改类A的几率。


2、可选接口

Swift 中的protocol 所有方法都必须被实现,不存在@optional 这样的概念。为了实现可选接口有两个办法:(一)@objc 、(二)协议扩展

// 只能被Class实现,struct和enum不可以
@objc protocol StreetSnapTableViewCellDelegate : NSObjectProtocol{
    // 可选
    @objc optional func deleteSeeFewerPhoto(cell : DJStreetSnapTableViewCell, indexPath: IndexPath?)
    func updateCellSubLikeInfoView(cell : DJStreetSnapTableViewCell, indexPath: IndexPath?, likeCount :Int)
    func updateCellSubSimilarsView(cell:UITableViewCell ,indexPath: IndexPath?, selectedIndex : Int)
}

3、协议扩展 protocol extension

// 在Swift2以后,我们可以对一个已有的protocol进行扩展。而扩展中实现的方法作为“实现扩展的类型”的“默认实现
// 通过提供protocol的extension,我们为protocol提供了默认实现,这相当于“变相”将protocol中的方法设定为了optional

protocol MyProtocol {
    func method()
}

//  默认实现 ,代替optional
extension MyProtocol {
    func method() {
        print("Called")
    }
}

struct MyStruct:MyProtocol {

}
MyStruct.method()   //输出: Called

struct MyStruct:MyProtocol {
    func method() {
        print("Called in struct")
    }
}
MyStruct.method()    //输出: Called in struct

4、mutating 修饰方法

“Structures and enumerations are value types. By default, the properties of a value type cannot be modified from within its instance methods.”
译:虽然结构体和枚举可以定义自己的方法,但是默认情况下,实例方法中是不可以修改值类型的属性。

protocol Vehicle {
    var wheel: Int {get set}
    // protocol的方法被mutating修饰,才能保证struct和enum实现时可以改变属性的值
    mutating func changeWheel()
}

struct Bike: Vehicle {
    var wheel: Int
    mutating func changeWheel() {
        wheel = 4
    }
}

class Car: Vehicle {
    var wheel: Int = 0
    func changeWheel() {
        wheel = 4
    }
}
var bike = Bike(wheel: 2)
bike.changeWheel()
print(bike.wheel)

let car = Car()
car.changeWheel()
print(car.wheel)

5、static 修饰静态方法

protocol Vehicle {
    static func wheel() -> Int
}

struct Bike: Vehicle {
    static func wheel() -> Int {
        return 2
    }
}

// static: protocol、enum、struct 。class:class 
class Car: Vehicle {
    class func wheel() -> Int {
        return 4
    }
}

6、protocol 组合

1、接口隔离原则:利用 Protocol Composition 可以把协议分得非常细,通过灵活的组合来满足特定要求。
2、「&」这个操作符可不仅仅能组合协议而已,也能组合「Type + Protocol」(类型+协议)。
3、匿名使用:func checkSounds(animal: KittenLike & DogLike)
4、别名:typealias CuteLike = KittenLike & TigerLike & DogLike

// 分工详细:**接口隔离原则**告诉我们在设计接口的时候要精简单一
protocol KittenLike {
    func meow() -> String
}

protocol DogLike {
    func bark() -> String
}

protocol TigerLike {
    func aou() -> String
}

// 不推荐
class MysteryAnimal: KittenLike, DogLike, TigerLike {
    func meow() -> String {
        return "meow"
    }
    
    func bark() -> String {
        return "bark"
    }
    
    func aou() -> String {
        return "aou"
    }
}
// 推荐
typealias CuteLike = KittenLike & TigerLike & DogLike
class CuteAnimal: CuteLike {
    func meow() -> String {
        return "meow"
    }
    
    func bark() -> String {
        return "bark"
    }
    
    func aou() -> String {
        return "aou"
    }
}

struct CheckAnimal {
    // 
    static func checkSounds(animal: KittenLike & DogLike) -> Bool {
        return true
    }
}

7、PATs, Protocols with Associated Type

参考:

在协议中使用范型:

//  Protocols with Associated Types 举例
struct Model {
    let age: Int
}

//协议,使用关联类型
protocol TableViewCell {
    associatedtype T
    func updateCell(_ data: T)
}

//遵守TableViewCell
class MyTableViewCell: UITableViewCell, TableViewCell {
    typealias T = Model
    func updateCell(_ data: Model) {
        // do something ...
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容

  • 01 举世皆浊我独清,众人皆醉我独醒。 于是屈大夫走在江边,心力交瘁披发行吟,叹楚怀王耳根太软,受小人挑拨,郁闷异...
    郑公子vega阅读 368评论 1 2
  • 天下熙熙皆为利来,天下攘攘皆为利往。 以前读到这句话的时候只觉得透着一种超脱世俗的清醒,能说出这样话的人一定是个不...
    张莫默阅读 191评论 0 0
  • 这是一个不知名的国度的一个不知名的花园。 这里四季烟雾缭绕,花园里,有着世界上各种各样的美丽花朵,但,每一种花都只...
    哭肿眼睛充近视阅读 229评论 0 1
  • 正如那花 你期待着用心灌溉 总不见花开 偶尔路过的风景 却让自己心生感慨 生活就是这样 越追求越离初心渐道渐远 缺...
    不惑而歌阅读 124评论 0 2
  • 1. ES6 class 注:(1)当一个组件需要调用Page组件时,只用写成 ,但实际上解析成了React.cr...
    何幻阅读 490评论 0 2