在Objective-C实例中,数据可以是公共的、受保护的或私有的。例如:

@interface Foo : NSObject
{
  @public
    int x;
  @protected:
    int y;
  @private:
    int z;
  }
-(int) apple;
-(int) pear;
-(int) banana;
@end

我没有发现任何提到的访问修饰符在Swift参考。是否有可能限制Swift中数据的可见性?


当前回答

语言语法没有关键字“public”,“private”或“protected”。这意味着一切都是公开的。当然,可以有一些替代方法来指定没有这些关键字的访问修饰符,但我在语言参考中找不到它。

其他回答

从Swift 3.0.1开始,共有4个访问级别,从最高(限制最少)到最低(限制最多)。


1. 公开和公共

允许在定义模块(目标)之外使用一个实体。在指定框架的公共接口时,通常使用开放或公共访问。

然而,开放访问仅适用于类和类成员,它与公共访问的区别如下:

公共类和类成员只能在定义模块(目标)内进行子类化和重写。 开放类和类成员可以在定义模块(目标)内外被子类化和重写。

// First.framework – A.swift

open class A {}

// First.framework – B.swift

public class B: A {} // ok

// Second.framework – C.swift

import First

internal class C: A {} // ok

// Second.framework – D.swift

import First

internal class D: B {} // error: B cannot be subclassed

2. 内部

启用在定义模块(目标)中使用的实体。在定义应用程序或框架的内部结构时,通常使用内部访问。

// First.framework – A.swift

internal struct A {}

// First.framework – B.swift

A() // ok

// Second.framework – C.swift

import First

A() // error: A is unavailable

3.fileprivate

将实体的使用限制到其定义的源文件。当在整个文件中使用特定功能块的实现细节时,通常使用文件私有访问来隐藏这些细节。

// First.framework – A.swift

internal struct A {

    fileprivate static let x: Int

}

A.x // ok

// First.framework – B.swift

A.x // error: x is not available

4. 私人

将实体的使用限制在其封闭声明范围内。当只在单个声明中使用特定功能块的实现细节时,通常使用私有访问来隐藏这些细节。

// First.framework – A.swift

internal struct A {

    private static let x: Int

    internal static func doSomethingWithX() {
        x // ok
    }

}

A.x // error: x is unavailable

对于Swift 1-3:

不,不可能。这里根本没有任何私有/受保护的方法和变量。

一切都是公开的。

更新 从Swift 4开始,可能会在这个帖子中看到其他答案

语言语法没有关键字“public”,“private”或“protected”。这意味着一切都是公开的。当然,可以有一些替代方法来指定没有这些关键字的访问修饰符,但我在语言参考中找不到它。

你可以使用的一个选项是将实例创建包装到一个函数中,并在构造函数中提供适当的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

使用协议、闭包和嵌套/内部类的组合,现在可以使用模块模式来隐藏Swift中的信息。它不是很干净,也不是很好读,但它确实有用。

例子:

protocol HuhThing {
  var huh: Int { get set }
}

func HuhMaker() -> HuhThing {
   class InnerHuh: HuhThing {
    var innerVal: Int = 0
    var huh: Int {
      get {
        return mysteriousMath(innerVal)
      }

      set {
       innerVal = newValue / 2
      }
    }

    func mysteriousMath(number: Int) -> Int {
      return number * 3 + 2
    }
  }

  return InnerHuh()
}

HuhMaker()
var h = HuhMaker()

h.huh      // 2
h.huh = 32 
h.huh      // 50
h.huh = 39
h.huh      // 59

innerVal和mysterousmath隐藏在这里,不被外部使用,试图挖掘对象的方法应该会导致错误。

我只是阅读了Swift文档的一部分,所以如果这里有缺陷,请指出来,我很想知道。