美文网首页
[swift 进阶]读书笔记-第十章:协议 C10P4 协议内

[swift 进阶]读书笔记-第十章:协议 C10P4 协议内

作者: liaoworkinn | 来源:发表于2019-05-06 13:06 被阅读0次

    第十章:协议 Protocol Protocol-Oriented Programming

    10.4 协议内幕 Protocol Internals

    本小节通过性能消耗的Demo来从底层讲了协议底层容器相关的知识点

    先看demo

    ///使用泛型参数的方法--性能高
    func f<C: CustomStringConvertible>(_ x: C) -> Int {
        return MemoryLayout.size(ofValue: x)
    }
    ///使用协议做参数的方法--性能低
    func g(_ x: CustomStringConvertible) -> Int {
        return MemoryLayout.size(ofValue: x)
    }
    f(5) // 8--正常一个Int类型在64位中Int的尺寸
    g(5) // 40
    

    明明是同一个Int为嘛后面的方法size就大很多。

    我们先看看g(5) 值为 40 是怎么组成的,这里面存在一个不透明的容器的概念(下图中标注的有)。

    40的长度是由三部分组成

    1.存储值的缓冲区(3个指针长度) 3 * 8 = 24

    2.元数据 8

    3.目击表(vtable 可以有0个或者多个 这里有1个) 8

    来来,看看我大笔一挥画的灵魂示意图:


    ProtocolInternals.jpeg

    下面我们来说说什么是目击表?(只做了解即可)

    目击表是让动态派发成为可能的关键,为一个特定的类型将协议的实现进行编码,表中会包含一个指向特定类型中的实现的入口

    知识点:如果我们合并多个协议,每多加一个协议,就会多 8 字节的数据块

    OC中的协议不需要封装在存在容器中,so~

    MemoryLayout<NSObjectProtocol>.size // 8

    性能调优

    不推荐❎

    //隐式打包
    func printProtocol(array: [CustomStringConvertible]) {
        print(array) 
    }
    

    推荐✅ swift标准库中大多数使用场景。

    //没有打包
    func printGeneric<A: CustomStringConvertible>(array: [A]) {
        print(array) 
    }
    

    相关文章

      网友评论

          本文标题:[swift 进阶]读书笔记-第十章:协议 C10P4 协议内

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