代码之家  ›  专栏  ›  技术社区  ›  Yakov Manshin

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

  •  -3
  • Yakov Manshin  · 技术社区  · 7 年前

    是否可以隐藏swift方法(这样它就不会出现在xcode自动完成和所有其他地方)而不声明它 private 是吗?

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

    1 回复  |  直到 7 年前
        1
  •  1
  •   Rob Napier    7 年前

    没有任何属性可以控制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将是唯一可以访问特殊方法的对象(尽管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()