如何在Swift中隐藏方法(因此该方法仍然可用)?

时间:2019-03-03 18:26:34

标签: swift xcode

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

这里的目标是使方法“不公开”(即,仅当用户知道确切名称时才可用)。

1 个答案:

答案 0 :(得分:1)

没有任何属性可以控制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()