考虑基础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
有没有办法修改静态make
,以便确实Dining.make()
会返回Dining
而Bath.make()
会返回Bath
?
(@Hamish指出可以使用init
和Self
模式,Method that returns object of type which was called from但是,我认为由于{{1}而无法实现}。)
因此。假设你有像
这样的代码instantiateViewController
事实上。 在运行时,d确实成为" Dining"而不是" Room"
太棒了。
但是。如果您在IDE中执行此操作
let d = Dining.make(blah blah)
它失败了 - 它认为d将成为一个房间, 不是餐饮 。
因此,您的所有代码都必须如下所示:
let d:Dining = Dining.make(blah blah)
哪个很糟糕。怎么解决?
注意只是TBC的解决方案是使静态变为通用,而不是像MartinR在这里的回答https://stackoverflow.com/a/33200426/294884以下答案中的示例代码。
答案 0 :(得分:3)
你可以这样做。
class RoomBase: RoomProtocol {
// things common to every room go here
required init() {}
}
您可以将
RoomBase
所有想要其他房间继承的内容放入。{/ p>
接下来,将make()
方法放入协议扩展名中。
protocol RoomProtocol: class {
init()
}
extension RoomProtocol where Self: RoomBase {
static func make() -> Self {
let room = Self()
// set up
return room
}
}
现在你可以写
了class Dining: RoomBase {}
class Bath: RoomBase { }
此代码可以使用
let dining: Dining = Dining.make()
let bath: Bath = Bath.make()
答案 1 :(得分:2)
我不想提供我自己的答案,但解决方案是..
所以问题是,在编辑时
let d = Dining.make()
"没有工作",你必须这样做
let d = Dining.make() as! Dining
( 在编译时工作 ,d成为餐饮:在编辑时它没有&#34;工作&#34;)< / p>
所以解决方案是
static func make()->Rooms {
let emplacedAndSetup = self.instantiate()
return emplacedAndSetup
}
变为
static func make<T: Rooms>()->T {
let emplacedAndSetup = self.instantiate() as! T
return emplacedAndSetup
}
这就是它。
注意 - 它完全可能AppzForLife
的解决方案有效和/或更好作为通用&#34; UIViewController自动实例化器&#34;,但这个是问题本身的答案。