We learned in the Protocol-Oriented Programming session at WWDC 2015 that Swift uses two different dispatch mechanisms for methods in protocol extensions.

 

Methods that are protocol requirements — that is, they are declared in the protocol itself — are dispatched dynamically, whereas methods that are not backed by a requirement use static dispatch.

I remember wondering last year why Swift made that distinction. It didn’t make sense to me and, like others, I was concerned it had the potential for lots of hard-to-find bugs. (Turns out it hasn’t been a problem in practice for me so far.) I recently came across this post by Kevin Ballard on Swift Evolution that includes the best explanation I have seen for why method dispatch in protocols works the way it does:

[Protocol extensions] are strictly static typing, all the way. Which makes sense, because there’s no virtual function table (or in Swift terms, protocol witness table) to put the methods into. Extensions can provide default implementations of protocol methods because the type that conforms to the protocol puts the extension method implementation into its own protocol witness table (and they only do this if the type doesn’t already implement the method itself). Since the protocol witness table only contains things defined in the protocol itself, protocol extension methods that aren’t part of the protocol don’t get put anywhere. So invoking one of those methods has no possible virtual function table to check, the only thing it can do is statically invoke the method from the extension. And this is why you can’t override them (or rather, why your override isn’t called if the method resolution is done via the protocol).

The only way to make protocol extension methods work via virtual dispatch is to define a new protocol witness table for the extension itself, but types that were defined without being able to see the extension won’t know to create and populate this protocol witness table. […]

The only other solution that comes to mind is turning all protocol dispatch into dynamic dispatch, which I hope you’ll agree is not a good idea.

So essentially, while protocols have a virtual function table, protocol extensions do not, and cannot easily have one because a type adopting the protocol won’t necessarily know about all extensions at compile time and therefore cannot add the extension methods to its own vtable. Opinions may vary whether dispatching protocols dynamically all the time would be a viable alternative, but it’s clearly not what the Swift team has in mind for the language.

If you want to learn more about how Swift types are laid out internally in memory and what information they contain, take a look at the Swift ABI document. It’s very interesting.

https://oleb.net/blog/2016/06/kevin-ballard-swift-dispatch/

Method Dispatch in Protocol Extensions的更多相关文章

  1. 多态,动态方法调度(dynamic method dispatch)?

    8.多态Polymorphism,向上转型Upcasting,动态方法调度(dynamic method dispatch) 什么叫多态?简言之,马 克 - t o - w i n:就是父类引用指向子 ...

  2. Which dispatch method would be used in Swift?-Existential Container

    In this example: protocol MyProtocol { func testFuncA() } extension MyProtocol { func testFuncA() { ...

  3. Which dispatch method would be used in Swift?

    In this example: protocol MyProtocol { func testFuncA() } extension MyProtocol { func testFuncA() { ...

  4. protocol

    For every object that can have a delegate, there is a corresponding protocol that declares themessag ...

  5. Java中的virtual method

    今天看jcvm的标准的 时候,看到有一个virtual method,感觉很疑惑,以前看Java的时候并没有发现有这类方法. 百度.Google了一下,才发现,Java中普通方法就是virtual m ...

  6. Method Invocation Expressions

      15.12.1. Compile-Time Step 1: Determine Class or Interface to Search   The first step in processin ...

  7. IOS开发protocol使用

    1.什么是protocol? protocol(协议)是用来定义对象的属性和行为,用于回调. 2.protocol分类? 协议中有三个修饰关键字@required和@optional和@propert ...

  8. Dynamic dispatch

    Dynamic dispatch动态调度.动态分发 In computer science, dynamic dispatch is the process of selecting which im ...

  9. An Introduction to Protocol Oriented Programming in Swift

    swift面向协议编程的根本原因在于值类型的存在:面向对象必须要有引用类型的支持: Protocol Oriented approach was introduced to resolve some ...

随机推荐

  1. 前端预览图片和H5canvas压缩图片上传

    思路是将图片抽样显示在canvas上,然后用通过canvas.toDataURL方法得到base64字符串来实现压缩. 1.base64转二进制文件 /** * dataURL to blob, re ...

  2. nextLine() 、nextInt()的跳过问题

    nextInt()  将输入的信息的下一个标记扫描为 int. nextLine() 此扫描器执行当前行,并返回跳过的输入信息. nextInt 会读取下面输入的 int类型的信息以回车作为结束,如果 ...

  3. IOS UI 设计 技术

    AutoLayout AutoLayout是一种基于约束的,描述性的布局系统. 程序员—-(cgrect)—>frame(center+bounds)    =====>   程序员—(N ...

  4. 【转】Google 发布 Android 性能优化典范(比较老,但很实用)

    2015年伊始,Google发布了关于Android性能优化典范的专题, 一共16个短视频,每个3-5分钟,帮助开发者创建更快更优秀的Android App.课程专题不仅仅介绍了Android系统中有 ...

  5. 软件开发-MSF方法(《构建之法》读书笔记2)

    MSF-微软解决方案框架,是一套大型系统开发指南,它描述了如何用组队模型.过程模型和应用模型来开发Client/Server结构的应用程序,是在微软的工具和技术的基础上建立并开发分布式企业系统应用的参 ...

  6. Javaweb的9大内置对象

    request(请求) response(响应) session(一个用户存放数据,安全) application(一个项目一般有一个,多用户共享存简单数据) out(输出,在页面输出内容) conf ...

  7. E20170519-ts

    numeric adj. 数字的; 数值的; nibble   vt. 啃,一点一点地咬(吃); rational adj. 理性的; 合理的; n. 合理的事物; [数] 有理数; numerato ...

  8. 扭曲效果 效率优化 GrapPass,CommandBuffer对比

    屏幕图像捕捉: Shader的GrabPass GrabPass可以很方便地捕获当前渲染时刻的FrameBuffer中的图像. 其原理就是从当前FrameBuffer中copy一份纹理,通过SetTe ...

  9. c语言类型修饰符及内存

    今天来学习一下c语言类型修饰符及内存分布 1.auto int a; 默认在内存 2.register int a; 限制变量定义在寄存器上的修饰符 编译器会尽量安排CPU的寄存器去存放这个a,如果寄 ...

  10. git修改push的注释信息

    修改还未push的注释: git commit --amend 修改后保存退出. 刚刚push到远端还没有人其他人下载或改动的: git commit --amend进入修改页面修改注释信息,修改后: ...