考虑一个基本的 UIViewController 类...
class Rooms: UIViewController {
class func instantiate()->Rooms {
}
static func make()->Rooms {
let emplacedAndSetup = self.instantiate()
// various kodes here
// very likely put s.view somewhere
return emplacedAndSetup
}
sundryOtherFunctionality()
}
(注意self.
之前instantiate()
似乎是获得“那个”实例化器所必需的。)
每个子类都知道自己的故事板 ID 以如何使用instantiateViewController
:
class Dining: Rooms {
override class func instantiate()->Dining { // returns a "Dining"
let d = stbd.instantiateViewController(
withIdentifier: "Some Specific Scene") as! Dining
return d
}
}
class Bath: Rooms {
override class func instantiate()->Bath { // returns a "Bath"
let b = stbd.instantiateViewController(
withIdentifier: "Some Other Scene") as! Bath
return b
}
}
你可以这样做,
let d = Dining.make()
let r = Bath.make()
唯一的小问题是,它返回基类。但见下文。所以在实践中你必须
let d = Dining.make() as! Dining
let r = Bath.make() as! Bath
有没有办法修改 staticmake
以便确实Dining.make()
返回 aDining
并Bath.make()
返回 a Bath
?
(@Hamish 指出可以使用一个init
andSelf
模式,方法返回被调用的类型的对象但是,我认为这是不可能的,因为instantiateViewController
.)
所以。假设您有类似的代码
let d = Dining.make(blah blah)
实际上。 在运行时, d 确实变成了“餐厅”,而不是“房间”
这太妙了。
但。如果您在 IDE 中执行此操作
let d:Dining = Dining.make(blah blah)
它失败了 - 它认为 d 将成为一个房间,而不是 Dining。
因此,您的所有代码都必须如下所示:
let d = Dining.make(blah blah) as! Dining
这很糟糕。怎么修?
请注意TBC 解决方案是使静态成为通用的,而不是 MartinR 在此处的答案https://stackoverflow.com/a/33200426/294884 示例代码在下面的答案中。