Swift中的访问修饰符对于扩展(extension)的影响

在Swift中,有一种结构extension,类似于OC中的Category分类,非常适合于对代码进行管理

同时,常用的访问修饰符有public、internal、private,而对于这三个访问修饰符,对extension的影响是各不一样的

在本文中,我将对同一文件下和不同文件下的extension、在本类和其他类调用,共四种情况进行分别介绍。

在介绍前,我先创建了一个非常简单的iOS项目,并新建了一个Person类和Person类的extension文件,如下图:

技术分享

其中,Person类的代码如下:

技术分享

Person+Extension文件中的代码如下:

技术分享

从上面的代码可以看到,在Person类本文件中的extension创建了两个函数,分别是getAge()和getGender()

在Person+Extension文件中创建了两个函数,叫sayHello()和sayGoodBye()

而具体的测试,将分别在Person本类的printSomething()和ViewController类的viewDidLoad()两个函数中分别进行

1、internal

internal是一个作用域介于public和private之间的访问修饰符,也是swift中默认的访问修饰符,通常是直接省略的

internal既不像public那么有开放性,也不像private那么封闭

a.同一文件下的extension,在其他类中调用:

在ViewController文件中直接调用Person类本文件extension中的方法如下:

技术分享

可以很清楚的看到,是可以很直接的调用到这个函数的

b.不同文件下的extension,在其他类中调用:

接下来调用Person+Extension的sayHello()函数:

技术分享

在这种情况下,非同一文件下的extension中的函数也是可以调用到的

c.同一文件下的extension,在本类中调用:

在Person类中测试结果如下:

技术分享

d.不同文件下的extension,在本类中调用:

在Person类中测试结果如下:

技术分享

结论:在internal或无修饰符情况下,不论extension中的函数和类文件是否在同一文件中,均可以顺利调用执行

2、private

private在各个编程语言中都表示私有方法/函数,在此我们均尝试一下使用private后两种情况下的extension函数

在开始前先

a.同一文件下的extension,在其他类中调用:

根据测试,即使是extension与类在同一文件中,在ViewController中也无法调用到被private修饰的函数getGender()

技术分享

b.不同文件下的extension,在其他类中调用:

测试后结果显示,extension与类在不同文件中的情况下,ViewController同样无法调用到被private修饰的函数sayGoodBye()

技术分享

c.同一文件下的extension,在本类中调用:

经测试,在此情况下,本类可以调用到与类在同一文件下的extension中被private修饰的函数

技术分享

d.不同文件下的extension,在本类中调用:

测试结果显示,与类不在同一文件的extension中的被private修饰的函数,即使在本类中也无法调用

技术分享

结论:在private修饰的extension函数中,仅有与类在同一文件的可以被顺利调用,其他情况下均无法被调用

3、public

public因其开放性,在任何位置均可以调用被public修饰的方法/函数,因此通常用于全局性的变量、属性或者方法。

在测试前将原来没有使用访问修饰符的getAge()和sayHello()函数前分别加上public修饰符。

而实际测试中,直接在方法前加上public修饰符会提示警告如下:

技术分享

技术分享

针对这种情况,Xcode编译器建议将public替换为internal,为解决这个问题,必须在类声明前也加上public才可以

技术分享

即证明:只有在public修饰的类中才可以存在被public修饰的函数

经修改后继续测试,测试结果依次如下:

a.同一文件下的extension,在其他类中调用:

技术分享

b.不同文件下的extension,在其他类中调用:

技术分享

c.同一文件下的extension,在本类中调用:

技术分享

d.不同文件下的extension,在本类中调用:

技术分享

结论:被public修饰的函数,不论是否与本类在同一文件,在本类和其他类中均可以被调用

综上所有结论如下:

访问修饰符 同一文件,其他类调用 不同文件,其他类调用 同一文件,本类调用 不同文件,本类调用
internal 可以被调用 可以被调用 可以被调用 可以被调用
private 不可以 不可以 可以被调用 不可以
public 可以被调用 可以被调用 可以被调用 可以被调用

 

 

 

 

表格注释:同一文件和不同文件仅代表函数所在extension是否与所在类是同一个文件

 

参考文章:https://github.com/bboyfeiyu/iOS-tech-frontier/blob/master/issue-4/Swift扩展的三个微妙细节.md

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。