为此,任何人都可能有一个干净的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 {
}
}
答案 0 :(得分:1)
由于Class1
和Class2
初始值设定项都需要符合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")
抱歉,我只是......