以静态方式返回UIViewController中的子类 [英] Returning the subclass in a UIViewController static
问题描述
class客房:UIViewController {
class func instantiate() - >房间{
}
static func make() - >房间{
let emplacedAndSetup = self.instantiate()
//各种kodes here
//很可能把s.view放在某处
return emplacedAndSetup
}
sundryOtherFunctionality()
}
(请注意 instantiate()$ c $>之前的
self。
看起来有必要获得那个实例化器。)
每个子类都知道它自己的故事板ID以便如何使用 instantiateViewController < code $:
class Dining:客房{
覆盖类func实例化() - >餐饮{ //返回一个Dining
让d = stbd.instantiateViewController(
withIdentifier:Some Specific Scene)as!餐厅
返回d
}
}
班Bath:客房{
覆盖class func instantiate() - > Bath {//返回一个Bath
让b = stbd.instantiateViewController(
withIdentifier:Some Other Scene)as! Bath
return b
}
}
您可以做到这一点,
let d = Dining.make()
let r = Bath.make()
唯一的小问题是,它返回基类。 但看下面。 因此,实际上你必须
let d = Dining.make()as!用餐
让r = Bath.make()as! Bath
有没有办法修改静态 make
确实 Dining.make()
会返回一个 Dining
和 Bath.make ()
会返回一个巴斯
?
(@Hamish指出,可以使用 init
和 Self 模式,返回被调用的类型对象的方法但是,我认为这是不可能的,因为
instantiateViewController
。)
所以。假设你有如下代码:
$ b
let d = Dining.make(blah blah)
实际上,
运行时,d确实变成了餐饮,而不是房间 这非常棒。
但是。如果您在IDE中执行此操作,那么您可以使用以下命令:
let d:Dining = Dining.make(blah blah)
失败 - 它认为d将是一个房间, 不是用餐 。
所以你所有的代码看起来都是这样的:
let d = Dining.make(blah blah)as!餐馆
这很吸引人。如何解决?
注意只要TBC的解决方案是使静态为通用的,而不像MartinR在这里的答案 https://stackoverflow.com/a/33200426/294884 下面答案中的代码示例
我不喜欢提供我自己的答案,但解决方案是......
所以问题是,在编辑时间
let d = Dining.make()
不起作用,您必须这样做
let d = Dining.make()as!餐厅
(它 在编译时工作 ,d变成餐饮:它在编辑时不工作。)
所以解决方案是
static func make() - >房间{
let emplacedAndSetup = self.instantiate()
return emplacedAndSetup
}
变为
静态func make< T:Rooms>() - > T {
let emplacedAndSetup = self.instantiate()as! T
return emplacedAndSetup
}
这就是它。
注意 - 完全可能 AppzForLife
的解决方案有效并且/或者更适合作为通用目的UIViewController auto-instantiator ,但这是问题本身的答案。
Consider a base UIViewController class...
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()
}
(Note the self.
before instantiate()
which seems to be necessary to get "that" instantiator.)
Each subclass knows its own storyboard ID to how use to 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
}
}
You can do this,
let d = Dining.make()
let r = Bath.make()
The only minor problem is, it returns the base class. BUT SEE BELOW. So in practice you have to
let d = Dining.make() as! Dining
let r = Bath.make() as! Bath
Is there a way to modify the static make
so that indeed Dining.make()
would return a Dining
and Bath.make()
would return a Bath
?
( @Hamish has pointed out that one could use an init
and Self
pattern, Method that returns object of type which was called from However, I think that's not possible due to the instantiateViewController
. )
So. Say you have code like
let d = Dining.make(blah blah)
in fact. At run time, d does become a "Dining", not a "Room"
that's fantastic.
But. If you do this in the IDE
let d:Dining = Dining.make(blah blah)
it fails - it thinks d is going to be a Room, not a Dining.
So all your code has to look like this:
let d = Dining.make(blah blah) as! Dining
which sucks. How to fix?
Note just TBC the solution is to make the static a generic, rather as in MartinR's answer here https://stackoverflow.com/a/33200426/294884 Example code in answer below.
I don't like to provide my own answer, but the solution is ..
So the problem is, at editor time
let d = Dining.make()
"doesn't work", you have to do this
let d = Dining.make() as! Dining
(It DOES work at compile time, d becomes a Dining: it doesn't "work" at editor time.)
So the solution is
static func make()->Rooms {
let emplacedAndSetup = self.instantiate()
return emplacedAndSetup
}
becomes
static func make<T: Rooms>()->T {
let emplacedAndSetup = self.instantiate() as! T
return emplacedAndSetup
}
So that's it.
Note - it's entirely possible AppzForLife
's solution works and/or is better as a general purpose "UIViewController auto-instantiator", but this is the answer to the question per se.
这篇关于以静态方式返回UIViewController中的子类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!