在 swift 中隐藏内部 class

Hiding inner class in swift

我试图隐藏一个内部 class 以便调用者不知道它。如果调用者愿意,他们可以使用 public 方法获取内部 class 的实例。但是调用者应该不能直接拿到里面的class.

展示我想要的示例:

class A {
    static func getSettings() -> Settings {
        return Settings()
    }
    class Settings {
        func turnOnSomeThing() {
            
        }
    }
}
 
class test {
    func testFunc() {
        A.getSettings().turnOnSomeThing() // correct way of calling
        A.Settings().turnOnSomeThing() // should not be possible
    }
}

这在Swift有可能吗?

为什么这两个调用在测试调用者中都有效?

两者目前都有效,因为:

  • 第一种情况,A.getSettings()...是一个classic getter,return是一个对象。我只是对每次都构造一个新的 Settings 感到困惑,但这是完全合法的。
  • 第二种情况,A.Settings()....调用Settings的构造函数创建了一个匿名对象,并在其上调用了一些方法。没关系,因为里面的class是public,但是很奇怪

你能把内部 class 设为私有吗?

您可以将内部 class 设为私有,以避免从外部世界访问它:

  • 这对于私人助手来说非常有效class完全不为外界所见。
  • 对于Settings这是不可能的,因为这个class的getSettings()returns对象对外界来说,这只有在外界的情况下才有意义知道class来对付它。

示例:

class A {
    static func getSettings() -> Settings {   // ERROR if Settings would be private 
        let helper = Helper() // purely internal use: Helper can be private :-)
        helper.demo()
        return Settings()
    }
    class Settings {              // making private is not possible (see above)
        func turnOnSomeThing() {
            print ("On")
        }
    }
    private class Helper {        // Cannot be used outside
       func demo() {
            print ("Demo")
        }
    }
}

但是设置怎么办?

如果你想 return Settings 反对外面的野外世界,你需要保持那个 class public。但是,如果你想避免外部世界误读内部 class 并避免从外部世界创建对象,你可以在构造函数上使用访问控制:

class A {
    static func getSettings() -> Settings {
        ...
    }
    class Settings {
        fileprivate init() {  /// <===  ACCESS CONTROL internal or fileprivate 
        }
        func turnOnSomeThing() {
            ...
        }
    }
}

这会阻止 A.Settings()... 形式的调用,但仅根据 swift access control:使用 internal 您仍然可以从另一个文件中调用构造函数相同的模块;使用 fileprivate 构造函数只能从您定义外部 class.

的源文件中调用

这种在保持 class 可用的同时使构造函数不可访问的技术经常用于 class 那些只能通过工厂创建的实例。