首页 > 解决方案 > 如何在 Swift 中隐藏一个方法(所以它仍然可用)?

问题描述

是否可以在不声明的情况下隐藏 Swift 方法(因此它不会出现在 Xcode 自动完成和所有其他地方)private

这里的目标是使该方法“未列出”(即仅当用户知道确切名称时才可用)。

标签: swiftxcode

解决方案


没有任何属性可以控制 IDE 的自动完成。通常,您会在此类方法前面加上前缀,_以明确它不是一般用途,并将所有此类方法组合在一起。

即使存在这样的属性(将来可能会有),它也绝对不会以任何有意义的方式隐藏该方法(因为它绝对会出现在生成的标头中)。所以这里唯一的目的是通过整理自动完成列表来使调用者更方便一点,并且_做得相当好。


只是为了完整性,有一种方法可以实现这一点,但你不想走这条路 IMO。如果这是一个 NSObject 子类,您可以使用动态调度。(在纯 Swift 中没有真正的等价物。)你真的不想这样做,它会产生警告,但这是可能的,而且这些方法不会出现在自动完成中,因为它们在技术上不可见.

class C: NSObject {
    @objc private func hidden() {
        print("Hidden")
    }

    @objc private func hiddenReturn() -> String {
        return "hidden"
    }
}

let c = C()

c.perform(Selector("hidden"))

let result = c.perform(Selector("hiddenReturn"))?.takeUnretainedValue() as! String

好的,现在我正在接受一系列奇怪的答案。您仍然不想这样做,但以下技术实际上可以用于某些事情。您可以传递指向方法的指针,并从不允许直接访问它们的地方调用它们。因此,假设您有一些“朋友”对象想要特殊访问某些私有方法。然后,您可以在创建过程中返回对该方法的引用。那么 Friend 将是唯一可以访问特殊方法的对象(尽管 Friend 可以将引用传递给其他对象,然后他们也可以访问)。例如:

class C {
    private func hidden() {
        print("hidden")
    }

    fileprivate class func create() -> (C, () -> Void) {
        let c = C()
        return (c, c.hidden)    // Return a reference to the private method
    }

    private init() {} // No creating us outside of create
}

class Friend {
    let c: C
    private let cHidden: () -> Void

    init() {
        (c, cHidden) = C.create()
        cHidden()   // Calling this function is the same as calling c.hidden()
    }
}

Friend()

推荐阅读