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

Swift将实现协议的类传递并存储到另一个类,swift,Swift,任何人都可能有一个干净的前swift-4解决方案 我见过类似的问题,但这是更具体的,其他解决方案在这里不起作用 注意:我无法在init中创建第二个viewcontnroller,它需要将数据传递给init,并且该数据来自服务器 protocol Cool { } class Class1 { let viewController: UIViewController let cool: Cool // Swift 4 : let viewController: UIVi

任何人都可能有一个干净的前swift-4解决方案

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

注意:我无法在init中创建第二个viewcontnroller,它需要将数据传递给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 { 
    }
}
protocolcool{}
一班{
让viewController:UIViewController
让我们冷静:冷静
//Swift 4:让viewController:UIViewController&酷
public init(content:T)其中T:Cool{
self.viewController=内容
self.cool=内容
}
func atSomePointLater(){
//怎么把它编译出来?
Class2(内容:viewController as!Cool,someText:textfield.text)
}
}
二级{
public init(content:T,someText:String),其中T:Cool{
}
}

免责声明:我尚未熟悉Swift 4。。希望这能有所帮助

首先,你没有一个UIViewController的子类,它遵循Cool。所以你需要这样做。UIViewController和酷炫,就像你在这里展示的一样,并没有提供足够的信息来说明可以在两者之间进行向下投射。之后,您需要将Class1中的viewcontroller更新为该子类。您将无法将UIViewController强制转换为酷,否则您将无法使用此处提供的内容

也许更多的上下文会有帮助,有助于
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 {

    }
}
公共协议{
init(content:T)其中T:Cool
}
类CoolController:UIViewController,Cool{
必需的初始化(内容:T),其中T:UIViewController,T:Cool{
super.init(nibName:nil,bundle:nil)
//你在这里需要什么就做什么。。?
}
必需的初始化?(编码器aDecoder:NSCoder){
fatalError(“初始化(编码者:)尚未实现”)
}
}
类别1:NSObject,很酷{
var viewController:CoolController?
酷:酷?
必需的初始化(内容:T),其中T:UIViewController,T:Cool{
super.init()
如果让cont=内容为?冷却{
冷却=继续
}否则,如果让控制器=内容为?UIViewController{
viewController=CoolController(内容:内容)
}
}
必需的初始化?(编码器aDecoder:NSCoder){
fatalError(“初始化(编码者:)尚未实现”)
}
/*
//Swift 4:让viewController:UIViewController&酷
*/
func atSomePointLater(){
//如何将其编译?///可选..在此处使用保护语句。。
如果让c=viewController{
类别2(内容:c,某些文本:无)
}
}
}
二级{
public init(content:T,someText:String?)其中T:Cool{
}
}
Sidenote-更新:我肯定会为Cool提供上下文,以及为什么要在纯对象类中实例化UIViewController。不是强制性的,但肯定很有趣。还有,我不能用cool=cool?变量在atSomePointLater()方法中,因为无法知道Cool和UIViewController可以降级(正如我上面所说的)


保持冷静。。很抱歉,我不得不…

因为
Class1
Class2
初始值设定项都需要一个符合
Cool
协议的视图控制器来处理它们的
内容
参数,我们可以将
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
protocolcool{}
T:酷{
让视图控制器:T
让我们冷静:冷静
公共初始化(内容:T){
self.viewController=内容
self.cool=内容
}
func atSomePointLater(){
让cls2=Class2(内容:viewController,someText:“Hello”)
打印(“第2类”,cls2)
}
}
二级{
public init(content:T,someText:String),其中T:Cool{
}
}
类MyVC:UIViewController{}
扩展MyVC:Cool{}//将MyVC标记为符合“Cool”协议
设vc1=MyVC()
设cls1=Class1(内容:vc1)
cls1.atSomePointLater()
//“viewController”和“cool”都引用“vc1”
打印(cls1.viewController==vc1)//true
print(cls1.cool)//与MyVC相同的实例,即vc1

通过使用CoolController而不是UIViewController,代码依赖于一个具体的类型,这与使用泛型的要点背道而驰:(.
var viewController:CoolController?
Hmm,实际上,我似乎找不到让UIViewController遵守它的方法:(…我认为这是一个与UIViewController的非最终类性质和使您的解决方案工作的方法(即:扩展要求等)混合在一起的子类型问题。查看这些帖子,这是我读到的内容:令人敬畏的是,不知道我为什么不考虑这样做:)