当前位置:  开发笔记 > IOS > 正文

标记快速扩展公共标识会将扩展中的属性更改为隐式公开还是内部?

如何解决《标记快速扩展公共标识会将扩展中的属性更改为隐式公开还是内部?》经验,为你挑选了1个好方法。

所以在Apple文档中:

扩展中添加的任何类型成员具有与要扩展的原始类型中声明的类型成员相同的默认访问级别.如果扩展公共或内部类型,则添加的任何新类型成员都将具有内部的默认访问级别.

给出UIView扩展的子类:

extension UIViewSubClass
{
    var helloWorld : String {
        get {
            return "helloWorld"
        }
    }
}

这将标记helloWorld为内部,我没有问题,我在基于Objective-C的项目中看不到它.

但是,如果我将扩展标记为公开:

public extension UIViewSubClass
{
    var helloWorld : String {
        get {
            return "helloWorld"
        }
    }
}

现在helloWorld在我的基于Objective-C的代码中出现,这意味着它被标记为公共.

但是,我没有看到苹果提到这一点,做到了吗?

我刚看到文档说公共类仍然具有隐含的内部级别.

public class SomePublicClass {          // explicitly public class
    public var somePublicProperty = 0    // explicitly public class member
    var someInternalProperty = 0         // implicitly internal class member
    private func somePrivateMethod() {}  // explicitly private class member
}

将公共扩展标记为扩展似乎与标记类定义具有不同的效果.这让我感到困惑.

有人可以帮助我,这应该是这样,还是这是一种快速的错误?我使用swift 2.1和Xcode 7.2



1> dfri..:

答案:是的,public在扩展名前放置访问级别修饰符(在您的情况下,特别是)会修改该扩展范围内所有新类型默认访问级别.

请注意,修饰符不会影响正在扩展的类/ struct/etc的访问级别(只有它的成员.但是,有些事情应该被考虑,我将在下面讨论.


在本次讨论中,我将发布一些关于Swift访问级别的重要事实.所有这些都来自Swift语言指南 - 访问控制 - 访问级别.

让我们首先确定您已经说过的内容:

如果您没有自己指定显式访问级别,则代码中的所有实体(具有一些特定的例外情况,如本章后面所述)都具有内部的默认访问级别 .

好的,这与你在问题中引用的内容一致:任何新的类型成员,无论是在类或结构定义中,都将具有内部的默认访问级别.

现在,让我们看一下您可以在扩展名前添加的访问级别修饰符:

您可以在类,结构或枚举可用的任何访问上下文中扩展类,结构或枚举.扩展中添加的任何类型成员具有与要扩展的原始类型中声明的类型成员相同的默认访问级别.如果扩展公共或内部类型,则添加的任何新类型成员都将具有内部默认访问级别.如果扩展私有类型,则添加的任何新类型成员都将具有私有默认访问级别.

或者,您可以使用显式访问级别修饰符(例如,专用扩展名)标记扩展,以为扩展中定义的所有成员设置新的默认访问级别.仍可以在单个类型成员的扩展中覆盖此新默认值.

这样可以解决问题.我们查看您的示例,并假设您的类UIViewSubClass具有访问级别public(或编译时错误,如下所示):

/* no access level modifier: default access level will be 'internal' */
extension UIViewSubClass
{
    // default access level used: internal
    var helloWorld : String { 
        get {
            return "helloWorld"
        }
    }
}

// modify default access level to public
public extension UIViewSubClass
{
    // default access level used: public
    var helloWorld : String { 
        get {
            return "helloWorld"
        }
    }
}

考虑到上面的讨论,我们希望helloWorld您的public extension ...内容internal在此上下文中标记为默认访问级别.在扩展的上下文中,访问级别修饰符的工作方式与应用于类型时的工作方式不同.

最后,我们应该指出public在扩展非公共类时使用访问修饰符将在Swift中产生编译时错误.所以在你的情况下:

如果UISubViewClass是一个internal或一个private类,那么public extension ...该类将产生编译时错误.

如果UISubViewClass是一个public类,那么添加public extension将是多余的,因为根据定义,公共类的默认访问修饰符已经是public.

我要说上面描述的错误并不是一个错误,以避免运行时错误,而是避免冗余(和混乱)代码:public成员类型privateinternal类永远不会使用它s公共访问级别.

class MyImplicitlyInternalClass {
    private var myExplicitlyPrivateVar = 0
    var myImplicitlyInternalVar = 0
    public var myExplicitlyPublicVar = 0 // warning, see (Note 1) below
        // redundant 'public': can never be accessed publicly
        // myExplicitlyPublicVar will behave as 'internal'
}

public extension MyImplicitlyInternalClass { // error, see (Note 2)
    var myNewVarIsInternal : Int { get { return 0 } } 
}
/* (Note 1) Compile type warning:
        "Declaring a public var for an internal class."

   (Note 2) Compile time error:
        "Extension of internal class cannot be declared public." 

   Summary: in theory, these two above are the same type of
            'faults', but only the latter is flagged as and error. */

因此,只有永远很有意义的使用访问级别修饰符的扩展使默认的访问级别更严格,即使用internal extension ...一个的public类或private extensioninternal类.

推荐阅读
虎仔球妈_459
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有