swift 中协议的使用 protocol

  • 1. 开发环境说明
  • 2. protocol的定义
  • 3. 协议应用举例说明
  • 3.1 首先定义相关协议
  • 3.2 定义游戏玩家的类
  • 3.3 定义跟踪器的类
  • 3.4 定义游戏中心类
  • 3.5 执行测试代码


1. 开发环境说明

系统版本:macOS Catalina 10.15.4
Xcode版本: Version 11.4.1 (11E503a)
swift版本: Apple Swift version 5.2.2 (swiftlang-1103.0.32.6 clang-1103.0.32.51).

2. protocol的定义

协议可被类、结构体、或枚举类型采纳以提供所需功能的具体实现。满足了协议中需求的任意类型都叫做遵循了该协议。

3. 协议应用举例说明

实现目标,以官方文档为背景,修改了一下,使其更简单,创建一个游戏玩家和游戏状态跟踪的类,将游戏和开始和结束做为游戏状态。

3.1 首先定义相关协议

protocol GameProtocol{
    var playerName:String{get}
    func gameStart();
}

protocol GameDelegateProtocol {
    func gameDidStart(game:GameProtocol)
    func gameDidEnd(game:GameProtocol)
}

GameProtocol协议要求,必须有一个可以get玩家姓名的属生,和一个开始游戏的方法。
GameDelegateProtocol要求,返回游戏开始和游戏结果的通知,并且需要告知跟踪的对象是哪个game:GameProtocol

3.2 定义游戏玩家的类

游戏玩家类,GamePlayer遵守GameProtocol协议,定义了相应的属性及方法,并且通过扩展Int 取得一个不大于sides的随机数,做为摇骰子游戏的结果,在游戏开始和结束时,分别判断是否指定了委托对应,并调用委托方法。

import Foundation

extension Int {
    static func randomWithSides(sides:Int) -> Int {
        assert(sides>0, "随机面的数量不能小于1")
        return Int(arc4random_uniform(UInt32(UInt8.max)))%sides+1
    }
}

class Dice {
    let mSides : Int
    //获得指定面数量的随机整数
    func roll() -> Int {
        return Int.randomWithSides(sides: mSides)
    }
    
    init(sides:Int=6) {
        mSides = sides
    }
}

//游戏玩家类
class GamePlayer:GameProtocol{
    var playerName:String
    var delegate:GameDelegateProtocol?
    init(name:String){
        playerName = name
    }
    
    func gameStart() {
        delegate?.gameDidStart(game: self)
        let d = Dice().roll();
        print("游戏玩家:\(playerName)-游戏运行结果:\(d)")
        delegate?.gameDidEnd(game: self)
    }
}

3.3 定义跟踪器的类

跟踪器的类GameTracker遵守GameDelegateProtocol协议定义的两个委拖方法,并且通过参数可以知道当前是哪个玩家的游戏状态。

//游戏状态跟踪类
class GameTracker:GameDelegateProtocol{
    
    func gameDidStart(game: GameProtocol) {
        print("游戏玩家:\(game.playerName)-gameDidStart")
    }
    
    func gameDidEnd(game: GameProtocol) {
        print("游戏玩家:\(game.playerName)-gameDidEnd")
    }
}

3.4 定义游戏中心类

GameCenter类中可以添加多个玩家,分别开始游戏,并通过日志信息可以看到执行的顺序。

//将所有玩家关联起来
class GameCenter {
    var names = [String]()

    func addPlayer(name:String){
        names.append(name)
    }
    func runGame(){
        guard names.count > 0 else {
            print("目前还没有玩家...")
            return
        }
        for n in names {
            let p = GamePlayer(name:n)
            p.delegate = GameTracker()
            p.gameStart()
        }
    }
}

3.5 执行测试代码

let g = GameCenter()
g.runGame() 
g.addPlayer(name: "xuan")
g.addPlayer(name: "wen")
g.addPlayer(name: "chao")
g.runGame()

程序运行结果如下:

目前还没有玩家...
游戏玩家:xuan-gameDidStart
游戏玩家:xuan-游戏运行结果:2
游戏玩家:xuan-gameDidEnd
游戏玩家:wen-gameDidStart
游戏玩家:wen-游戏运行结果:1
游戏玩家:wen-gameDidEnd
游戏玩家:chao-gameDidStart
游戏玩家:chao-游戏运行结果:6
游戏玩家:chao-gameDidEnd