在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中数据的可见性?
当前回答
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() { }
}
为了获得更好的可维护代码,这可能是一个好主意。你可以很容易地切换到非私有(例如单元测试),只需要改变一个词。
苹果公司的文档
其他回答
当人们谈论在Swift或ObjC(或ruby或java或…)中创建“私有方法”时,这些方法并不是真正的私有方法。他们周围没有实际的访问控制。任何语言只要能够提供一点内省功能,就可以让开发人员从类之外获得这些值,如果他们真的想要的话。
因此,我们在这里真正谈论的是一种定义面向公众的接口的方法,该接口仅呈现我们想要的功能,并“隐藏”其余我们认为是“私有”的功能。
Swift声明接口的机制就是协议,它可以用于此目的。
protocol MyClass {
var publicProperty:Int {get set}
func publicMethod(foo:String)->String
}
class MyClassImplementation : MyClass {
var publicProperty:Int = 5
var privateProperty:Int = 8
func publicMethod(foo:String)->String{
return privateMethod(foo)
}
func privateMethod(foo:String)->String{
return "Hello \(foo)"
}
}
请记住,协议是第一类类型,可以在类型可以使用的任何地方使用。而且,当以这种方式使用时,它们只公开自己的接口,而不是实现类型的接口。
因此,只要你在参数类型中使用MyClass而不是MyClassImplementation,等等,它都应该工作:
func breakingAndEntering(foo:MyClass)->String{
return foo.privateMethod()
//ERROR: 'MyClass' does not have a member named 'privateMethod'
}
在一些直接赋值的情况下,你必须显式地使用类型,而不是依赖Swift来推断它,但这似乎并不是一个问题:
var myClass:MyClass = MyClassImplementation()
以这种方式使用协议是语义上的,相当简洁,而且在我看来很像我们在ObjC中为此目的使用的类扩展。
你可以使用的一个选项是将实例创建包装到一个函数中,并在构造函数中提供适当的getter和setter:
class Counter {
let inc: () -> Int
let dec: () -> Int
init(start: Int) {
var n = start
inc = { ++n }
dec = { --n }
}
}
let c = Counter(start: 10)
c.inc() // 11
c.inc() // 12
c.dec() // 11
till swift 2.0 there were only three access level [Public, internal, private] but in swift 3.0 apple added two new access level which are [ Open, fileType ] so now in swift 3.0 there are 5 access level Here I want to clear the role of these two access level 1. Open: this is much similar to Public but the only difference is that the Public can access the subclass and override, and Open access level can not access that this image is taken from Medium website and this describe the difference between open and public access
现在是第二个新的访问级别 2. 文件类型是更大版本的私有或更低的访问级别比内部 fileType可以访问[class, struct, enum]的扩展部分 而且private不能访问扩展部分的代码,它只能访问 词法作用域 这张照片取自Medium网站,描述了fileType和Private访问级别之间的区别
在Beta 6中,文档指出有三种不同的访问修饰符:
公共 内部 私人
这三点适用于类、协议、函数和属性。
public var somePublicVariable = 0
internal let someInternalConstant = 0
private func somePrivateFunction() {}
有关更多信息,请检查访问控制。
从Xcode 6 beta 4开始,Swift就有了访问修饰符。发布说明如下:
Swift访问控制分为三种访问级别: 私有实体只能从定义它们的源文件中访问。 内部实体可以在目标中定义它们的任何地方访问。 公共实体可以从目标中的任何地方访问,也可以从导入当前目标模块的任何其他上下文访问。
隐式默认值是内部的,因此在应用程序目标中,您可以关闭访问修饰符,除非在需要更严格限制的地方。在框架目标中(例如,如果你嵌入一个框架来在应用程序和共享或Today视图扩展之间共享代码),使用public指定你想要向框架的客户端公开的API。