iOS 访问控制权限【Swift】

iOS 访问控制权限【Swift】,第1张

对于每个语言都有属于自己的访问控制权限
对于Java来说:OC中提供了4个访问控制符: @private @package @protected @public 。
对于iOS开发工程师使用OC语言的来说:OC中提供了4个访问控制符: @private @package @protected @public 。
而对于iOS开发工程师还有一种是使用Swift来🔨代码的,那么对应Swift的访问控制 open, public, internal, fileprivate, private这五个。

open : module以外可以访问、重写或者继承。
public: module以外可以访问、不能重写或者继承。
internal(默认):当前module可用
fileprivate: 当前file可见
private:当前声明区域可见
当你的module的某些类或者方法不想对外提供继承或者重写的权限时可以使用public,而不必使用final。
一个建议是自定义类默认设置为final而不是默认的final(除非有继承的需求),这样可以提高编译速度。

来看看代码

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        let a = A.init()
        a.method()
    }
    

}

class A {
    open var opena = 10 //module以外可以访问、重写或者继承。
    public var publicb = 10 //module以外可以访问、不能重写或者继承。
    internal var internalc  = 10 //当前module可用
    fileprivate var fileprivated = 10 // 当前file可见
    private var privatee = 10 //当前声明区域可见
  
}

extension A {
    func method() {
        print(opena)
        print(publicb)
        print(internalc)
        print(fileprivated)
        print(privatee)
    }
}


都在一个model里面 ,没有问题!!

而这个如果要调用A类里面的成员变量除了用private声明的不可以被调用,其余都有正常被调用。因为private定义为了私有也就只能在A类使用。

而这时候如果我们把extension放在不同文件里就会发生使用fileprivated声明的变量报错了,'xxxxxx' is inaccessible due to 'fileprivate' protection level就是访问权限问题!!fileprivated也就是文件内私有,也在当前的.switf可用。

那internal、public和opena如何测试?如何在不同module呢?
先回答最后一个问题,如何在不同Module呢?可以使用打包的方式。那如何打包呢?可以参考小编的打包静态库教程

首先搞一个静态库静态库里面有一个Utils文件下面对应的类及代码如下:

open class UtilsAA: NSObject {
    
    open var openA = 10
    public var publicB = 199
    var c = 1000
}


public class UtilsBB: NSObject{
    open var openD = 10
    public var publicE = 199
    var F = 1000
}

class UtilsCC: NSObject {
    open var openG = 10
    public var publicH = 199
    var i = 1000
}

CC这边不是用任何访问权限,那么对应的就是默认的internal。在不同的Module下面调用情况如下

代码如下:

    override func viewDidLoad() {
        super.viewDidLoad()
        let a =  UtilsAA.init()
        print(a.openA)
        print(a.publicB)
        //error: 'c' is inaccessible due to 'internal' protection level
        print(a.c)
        
        let b = UtilsBB.init()
        print(b.openD)
        print(b.publicE)
        //error:'F' is inaccessible due to 'internal' protection level
        print(b.F)
        
        //Cannot find 'UtilsCC' in scope
        let c = UtilsCC.init()
        
    }

也就是如果不使用访问修饰符或者使用了internal修饰符,那么可以在整个module都可以访问的到。
openpublic在module外都可以访问的到,再来说说这两个最大的区别就是能不能被继承和重写。我们不改变静态库里的代码,在使用静态库的地方分别对他进行继承看看效果:
效果如下:

class UtilsAAAA: UtilsAA {
    func sayNumber()  {
        print(openA)
        print(publicB)
    }
}
//error:Cannot inherit from non-open class 'UtilsBB' outside of its defining module
class UtilsBBBB: UtilsBB{
    func sayNumber()  {
        print(openD)
        print(publicE)
    }
}

Cannot inherit from non-open class ‘UtilsBB’ outside of its defining module中文意思为:无法从其定义模块之外的非开放类“UtilsBB”继承。也就是因为我们的UtilsBB这个类是用Public修饰的,而使用了Public的类在module外是不能被继承的,只有使用open修饰符才能在module外被继承。
再来看看重写的时候open和public的区别,同样的在静态库中增加

open class UtilsDD: NSObject {
    open func UtilsDD_sayHello(){
        print("say hello")
    }
    
    public func UtilsDD_sayHi(){
        print("say Hi")
    }
}

在调用静态库的时候重写里面的方法

class UtilsDDDD: UtilsDD {
    //error: Overriding non-open instance method outside of its defining module
    override func UtilsDD_sayHi() {
        print("Override !!")
    }
    
    override func UtilsDD_sayHello() {
        print("Override !!")
    }
}

可见,Overriding non-open instance method outside of its defining module也已经告诉我们了,非open对象修饰的是不能被重写的。

都看到这了还不来一个一键三连?????

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/996453.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存