20 协议

协议的格式

  • 协议的定义方式与类,结构体,枚举的定义都非常相似
protocol SomeProtocol {
    // 协议方法
}
  • 遵守协议的格式
class SomeClass: SomeSuperClass, FirstProtocol, AnotherProtocol {
    // 类的内容
    // 实现协议中的方法
}

协议的基本使用

  • 定义协议和遵守协议
// 1.定义协议
protocol SportProtocol {
    func playBasketball()
    func playFootball()
}

// 2.遵守协议
// 注意:默认情况下在swift中所有的协议方法都是必须实现的,如果不实现,则编译器会报错
class Person : SportProtocol {
    var name : String?
    var age : Int = 0

    // 实现协议中的方法
    func playBasketball() {
        print("人在打篮球")
    }

    func playFootball() {
        print("人在踢足球")
    }
}
  • 协议之间的继承
protocol CrazySportProtocol {
    func jumping()
}

protocol SportProtocol : CrazySportProtocol {
    func playBasketball()
    func playFootball()
}

代理设计模式

  • 协议继承用于代理设计模式
protocol BuyTicketProtocol : NSObjectProtocol {
    func buyTicket()
}

class Person {
    // 1.定义协议属性
    weak var delegate : BuyTicketProtocol
    
    // 2.自定义构造函数
    init (delegate : BuyTicketProtocol) {
        self.delegate = delegate
    }
    
    // 3.行为
    func goToBeijing() {
        delegate.buyTicket()
    }
}


class HuangNiu: BuyTicketProtocol {
    func buyTicket() {
        print("买了一张火车票")
    }
}

let p = Person(delegate: HuangNiu())
p.goToBeijing()

协议中方法的可选

// 1.定义协议
@objc protocol SportProtocol {
    func playBasketball()
    
    @objc optional func playFootball()
}

// 2.遵守协议
class Person : SportProtocol {
    var name : String?
    var age : Int = 0
    
    // 实现协议中的方法
    func playBasketball() {
        print("人在打篮球")
    }
}
  • 注意:
    • 要实现协议可选方法,上面代码示例中的两个 @objc 不能少,否则会报错如下:

error: 'optional' can only be applied to members of an @objc protocol
optional func playFootball()
^

error: 'optional' requirements are an Objective-C compatibility feature; add '@objc'
optional func playFootball()
^
@objc

协议的使用注意

  • 协议的瘦身

定义 Swift 中的协议时,为了优化性能,可以不继承 NSObjectProtocol 协议,因为 NSObjectProtocol 中默认实现了很多方法,而这些方法我们不一定会用到,可以等需要时在继承。

但会出现下面的问题:

swift代理weak修饰报错.png

报错意思是:weak 只能修饰 class 和 class-bound protocol 类型。

我自定义的协议 MainViewControllerDelegate 没有继承 NSObjectProtocol,所以自然也就不是 class-bound protocol 类型,也就不能用 weak 修饰。但不用 weak 修饰,又可能会造成循环引用的问题。

解决:
可以继承 class 类型

import UIKit

protocol MainViewControllerDelegate : class {
    func deleFuc1() -> Int
}


class MainViewController: UIViewController {
    // 这里的 weak 不会报错
    weak var delegate : MainViewControllerDelegate?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
    }

}

其他资料

Swift中的Protocol知道这些就够了

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容