在Objective-C实例中,数据可以是公共的、受保护的或私有的。例如:
@interface Foo : NSObject
{
@public
int x;
@protected:
int y;
@private:
int z;
}
-(int) apple;
-(int) pear;
-(int) banana;
@end
我没有发现任何提到的访问修饰符在Swift参考。是否有可能限制Swift中数据的可见性?
在Objective-C实例中,数据可以是公共的、受保护的或私有的。例如:
@interface Foo : NSObject
{
@public
int x;
@protected:
int y;
@private:
int z;
}
-(int) apple;
-(int) pear;
-(int) banana;
@end
我没有发现任何提到的访问修饰符在Swift参考。是否有可能限制Swift中数据的可见性?
当前回答
从Xcode 6 beta 4开始,Swift就有了访问修饰符。发布说明如下:
Swift访问控制分为三种访问级别: 私有实体只能从定义它们的源文件中访问。 内部实体可以在目标中定义它们的任何地方访问。 公共实体可以从目标中的任何地方访问,也可以从导入当前目标模块的任何其他上下文访问。
隐式默认值是内部的,因此在应用程序目标中,您可以关闭访问修饰符,除非在需要更严格限制的地方。在框架目标中(例如,如果你嵌入一个框架来在应用程序和共享或Today视图扩展之间共享代码),使用public指定你想要向框架的客户端公开的API。
其他回答
Swift 4 / Swift 5
正如Swift文档-访问控制中提到的,Swift有5个访问控制:
开放和公共:可以从它们的模块实体和导入定义模块的任何模块实体中访问。 Internal:只能从其模块的实体中访问。这是默认的访问级别。 文件私有和私有:只能在您定义的有限范围内进行有限访问。
open和public的区别是什么?
open和之前版本的Swift中的public是一样的,它们允许来自其他模块的类使用和继承它们,即:它们可以从其他模块继承子类。此外,它们允许来自其他模块的成员使用和重写它们。同样的逻辑也适用于它们的模块。
Public允许来自其他模块的类使用它们,但不能继承它们,即:它们不能从其他模块子类化。此外,它们允许来自其他模块的成员使用它们,但不允许重写它们。对于它们的模块,它们具有相同的open's逻辑(它们允许类使用和继承它们;它们允许成员使用和重写它们)。
文件私有和私有的区别是什么?
私有文件可以从他们的整个文件访问。
Private只能从它们的单个声明和同一文件中该声明的扩展进行访问;例如:
// Declaring "A" class that has the two types of "private" and "fileprivate":
class A {
private var aPrivate: String?
fileprivate var aFileprivate: String?
func accessMySelf() {
// this works fine
self.aPrivate = ""
self.aFileprivate = ""
}
}
// Declaring "B" for checking the abiltiy of accessing "A" class:
class B {
func accessA() {
// create an instance of "A" class
let aObject = A()
// Error! this is NOT accessable...
aObject.aPrivate = "I CANNOT set a value for it!"
// this works fine
aObject.aFileprivate = "I CAN set a value for it!"
}
}
Swift 3和Swift 4的访问控制有什么不同?
正如在SE-0169提案中提到的,Swift 4唯一的改进是私有访问控制范围被扩展,可以从同一文件中的声明扩展中访问;例如:
struct MyStruct {
private let myMessage = "Hello World"
}
extension MyStruct {
func printMyMessage() {
print(myMessage)
// In Swift 3, you will get a compile time error:
// error: 'myMessage' is inaccessible due to 'private' protection level
// In Swift 4 it should works fine!
}
}
因此,不需要将myMessage声明为文件私有以在整个文件中可访问。
对于Swift 1-3:
不,不可能。这里根本没有任何私有/受保护的方法和变量。
一切都是公开的。
更新 从Swift 4开始,可能会在这个帖子中看到其他答案
Swift 3和4也为变量和方法的访问级别带来了很多变化。Swift 3和4现在有4个不同的访问级别,其中开放/公共访问是最高(限制最少)的访问级别,私有访问是最低(限制最多)的访问级别:
private functions and members can only be accessed from within the scope of the entity itself (struct, class, …) and its extensions (in Swift 3 also the extensions were restricted) fileprivate functions and members can only be accessed from within the source file where they are declared. internal functions and members (which is the default, if you do not explicitly add an access level key word) can be accessed anywhere within the target where they are defined. Thats why the TestTarget doesn't have automatically access to all sources, they have to be marked as accessible in xCode's file inspector. open or public functions and members can be accessed from anywhere within the target and from any other context that imports the current target’s module.
有趣:
与其将每个单独的方法或成员标记为“private”,你可以在类/结构的扩展中覆盖一些方法(例如典型的helper函数),并将整个扩展标记为“private”。
class foo { }
private extension foo {
func somePrivateHelperFunction01() { }
func somePrivateHelperFunction02() { }
func somePrivateHelperFunction03() { }
}
为了获得更好的可维护代码,这可能是一个好主意。你可以很容易地切换到非私有(例如单元测试),只需要改变一个词。
苹果公司的文档
从Xcode 6 beta 4开始,Swift就有了访问修饰符。发布说明如下:
Swift访问控制分为三种访问级别: 私有实体只能从定义它们的源文件中访问。 内部实体可以在目标中定义它们的任何地方访问。 公共实体可以从目标中的任何地方访问,也可以从导入当前目标模块的任何其他上下文访问。
隐式默认值是内部的,因此在应用程序目标中,您可以关闭访问修饰符,除非在需要更严格限制的地方。在框架目标中(例如,如果你嵌入一个框架来在应用程序和共享或Today视图扩展之间共享代码),使用public指定你想要向框架的客户端公开的API。
在Beta 6中,文档指出有三种不同的访问修饰符:
公共 内部 私人
这三点适用于类、协议、函数和属性。
public var somePublicVariable = 0
internal let someInternalConstant = 0
private func somePrivateFunction() {}
有关更多信息,请检查访问控制。