Swift传递并将实现协议的类存储到另一个类

时间:2017-06-22 20:58:56

标签: swift

为此,任何人都可能有一个干净的pre-swift-4解决方案吗?

我见过类似的问题,但这是更具体的,而其他解决方案在这里不起作用

注意:我无法在init中创建第二个viewCotnroller,它需要将数据传递给init,并且该数据来自服务器

protocol Cool { }

class Class1 {

    let viewController: UIViewController
    let cool: Cool
    // Swift 4 : let viewController: UIViewController & Cool

    public init<T: UIViewController>(content: T) where T: Cool {
        self.viewController = content
        self.cool = content
    }

    func atSomePointLater () {
        // Ho to get this to compile?
        Class2(content: viewController as! Cool, someText: textfield.text)
    }
}

class Class2 {
    public init<T: UIViewController>(content: T, someText: String) where T: Cool { 
    }
}

2 个答案:

答案 0 :(得分:1)

由于Class1Class2初始值设定项都需要符合Cool协议的content协议的视图控制器,因此我们可以将Class1作为通用类我们会调用T的类型(其中T的类型为UIViewController且符合Cool协议)。

由于viewController始终属于T类型,因此我们可以在其声明中更改其类型。 Class2初始值设定项现在接受viewController作为参数,因为它现在不仅仅是UIViewController,而且还符合Cool协议。

protocol Cool { }

class Class1<T: UIViewController> where T: Cool {

    let viewController: T
    let cool: Cool

    public init(content: T) {
        self.viewController = content
        self.cool = content
    }

    func atSomePointLater () {
        let cls2 = Class2(content: viewController, someText: "Hello")
        print("Class 2", cls2)
    }
}

class Class2 {
    public init<T: UIViewController>(content: T, someText: String) where T: Cool {

    }
}


class MyVC: UIViewController { }
extension MyVC: Cool {}   // Mark MyVC as conforming to 'Cool' protocol

let vc1 = MyVC()

let cls1 = Class1(content: vc1)
cls1.atSomePointLater()

// Both 'viewController' and 'cool' reference 'vc1'
print(cls1.viewController == vc1)   // true
print(cls1.cool)                    // the same instance of MyVC, i.e. vc1

答案 1 :(得分:0)

免责声明:我还没有熟悉Swift 4 ..所以希望这会有所帮助。

首先,你没有UIViewController的子类,它遵循Cool。所以你需要这样做。 UIViewController和你这里展示的Cool并没有提供足够的信息来暗示可以在两者之间进行向下转换。之后,您需要将Class1中的viewcontroller更新为该子类。你不能将UIViewController转换为Cool,否则你将提供你所提供的内容。

为了帮助实现Cool的目的,可能会有更多的背景信息。我的意思是,我的意思是我不知道你需要Cool / Cool对于你的用例通常是什么public protocol Cool { init<T: UIViewController>(content: T) where T: Cool } class CoolController : UIViewController, Cool { required init<T>(content: T) where T : UIViewController, T : Cool { super.init(nibName: nil, bundle: nil) //Do whatever you need here..? } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } } class Class1: NSObject, Cool { var viewController: CoolController? var cool: Cool? required init<T>(content: T) where T : UIViewController, T : Cool { super.init() if let cont = content as? Cool { cool = cont } else if let controller = content as? UIViewController{ viewController = CoolController(content: content) } } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } /* // Swift 4 : let viewController: UIViewController & Cool */ func atSomePointLater() { // Ho to get this to compile? ///Optionally.. use a GUARD statement here.. if let c = viewController { Class2(content: c, someText: nil) } } } class Class2 { public init<T: UIViewController>(content: T, someText: String?) where T: Cool { } } ,但是下面的内容可以全部编译。

Cool

Sidenote - 更新:我肯定会为Cool提供上下文,以及为什么要在仅限对象的类中实例化UIViewController。不是强制性的,但绝对有趣。另外,我不能使用酷=酷?你的atSomePointLater()方法中的变量,因为无法知道Cool和UIViewController可以被降级(如上所述)。

留下@GetMapping("/tesget")抱歉,我只是......