在swift中隐藏协议的采用

时间:2014-10-21 04:22:12

标签: swift

我想知道我是否可以在swift中隐藏采用协议。

在Objective-C中,我将在m.-文件中使用私有头来隐藏我不希望暴露给外部的协议。 这样的事情可以迅速吗?在协议之前设置“私有”不起作用,显然:)

2 个答案:

答案 0 :(得分:10)

修改:找到一种隐藏它的简单方法。至少从xcode快速帮助信息:只需将采用和实现放在你的类的扩展中,它就不会出现在那里。

原始答案:

我想出了这个例子,受到Java内部类的启发。这里MyVC没有公开它为内部目的实现UICollectionViewDelegate,而委托实现可以访问MyVC的私有变量。

public class MyVC: UIViewController {

    private let a = 4 as Int
    private var hiddenDelegate: HiddenDelegateImpl?

    public override func viewDidLoad() {
        super.viewDidLoad()
        hiddenDelegate = HiddenDelegateImpl(outer: self)
        innerCollectionView.delegate = hiddenDelegate
    }
}

private class HiddenDelegateImpl: NSObject, UICollectionViewDelegate {

    private weak var outer: MyVC?

    init(outer: MyVC) {
        self.outer = outer
        super.init()
    }

    private func doStuff() -> Int {
        // can access private variables of outer class
        return outer?.a
    }

    // implement delegate methods here
}

请注意HiddenDelegateImpl也可能是MyVC的内部类,我选择将其放在外面以便于阅读。

与内部类的Java实例相比,需要存在外部类的实例。由于Swift不是这种情况,我们需要outer解决方法。

还有this nice example专注于委托实施。

编辑:使委托中的外部类中的实例变量保留它,并且对外部类的引用为弱以避免保留周期。

答案 1 :(得分:-1)

自从帖子以来,语言可能已经发生了变化,但它对我有用。这是我想隐藏初始化程序以控制对象的生命周期并执行后期处理的示例。在这种情况下,我希望根据呼叫者的配置来跟踪和发送分析。

private protocol Reportable {
    init()
    var people:[String:AnyObject] { get }
    var track:[String:AnyObject] { get }
}


public class Analytics {

    public final class Alpha: Reportable {

        var thingOne: String?
        var thingTwo: String?

        private init() {}
        private var people:[String:AnyObject] { return [:] }
        private var track:[String:AnyObject] { return [:] }
    }

    public final class Bravo: Reportable {

        var thingOne: String?
        var thingTwo: String?

        private init() {}
        private var people:[String:AnyObject] { return [:] }
        private var track:[String:AnyObject] { return [:] }
    }


    public static func alpha(configure:Alpha -> ()) {
        return report(configure)
    }

    public static func bravo(configure:Bravo -> ()) {
        return report(configure)
    }


    private static func report<T:Reportable>(configure:T -> ()) {
        let event = T()
        configure(event)
        Analytics.doSomething()
    }


    static func doSomething() {

    }
}

// separate file
func clientCode() {

    Analytics.alpha { event in

        event.track // error

        event.thingOne = "foo"
        event.thingTwo = "bar"  }

    Analytics.bravo { event in
        event.thingOne = "foo"
        event.thingTwo = "bar"  }

}