以静态方式返回UIViewController中的子类 [英] Returning the subclass in a UIViewController static

查看:196
本文介绍了以静态方式返回UIViewController中的子类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  class客房:UIViewController {
class func instantiate() - >房间{
}

static func make() - >房间{
let emplacedAndSetup = self.instantiate()
//各种kodes here
//很可能把s.view放在某处
return emplacedAndSetup
}

sundryOtherFunctionality()
}

(请注意 instantiate()之前的 self。看起来有必要获得那个实例化器。)



每个子类都知道它自己的故事板ID以便如何使用 instantiateViewController < code $:

  class Dining:客房{
覆盖类func实例化() - >餐饮{ //返回一个Dining
让d = stbd.instantiateViewController(
withIdentifier:Some Specific Sc​​ene)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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆