美文网首页程序员iOS Developer
【iOS 开发】用泛型简化 instantiateViewCon

【iOS 开发】用泛型简化 instantiateViewCon

作者: KyXu | 来源:发表于2016-11-03 16:29 被阅读1230次

使用 storyboard 的时候,我们经常会写出下面这样的代码,用来跳转到其他页面

if let editVC = self.storyboard?.instantiateViewController(withIdentifier: "EditVC") as? EditVC {
    self.navigationController?.pushViewController(editVC, animated: true)
}

最多改成这样

guard let editVC = self.storyboard?.instantiateViewController(withIdentifier: "EditVC") as? EditVC else { return }

实在是太冗长了,简化第一步,或许我们可以直接将 <code>EditVC</code> 这个类型字符串化变成 <code>"EditVC"</code>,代码变成:

guard let editVC = self.storyboard?.instantiateViewController(withIdentifier: String(describing: EditVC.self)) as? EditVC else { return }

嗯,更长了,但是既然 <code>EditVC</code> 使用了两次,这使得我们有机会把这个过程封装成一个函数,而 <code>EditVC</code> 是唯一需要传递的参数

func instantiateVC(vc:UIViewController) -> UIViewController? {
    let id = String(describing: vc.self)
    return storyboard?.instantiateViewController(withIdentifier: id)
}

// how to use
guard let editVC = instantiateVC(vc: EditVC()) as? EditVC else { return }

封装之后依然尴尬:

  1. 因为我们不能确定每次都需要函数返回 <code>EditVC</code> ,所以只能用 <code>UIViewController</code> 当做返回值,这使得我们还需要再加上 <code>as? EditVC</code> 去做类型转换,相当于还是手动使用了两次 <code>EditVC</code> ,而不是一次
  2. 传入的参数是 <code>EditVC()</code> 而不是 <code>EditVC</code> ,看起来丑陋

一次解决两个问题的答案是:泛型!

我们在函数中限定泛型 <code>T</code> 为 <code>UIViewController</code> ,但 <code>T</code> 具体是我们的 App 中的哪个子类我们不去管,通过函数的参数来指定 T 的具体类型,随后确定出我们函数的返回值为那个我们指定的 <code>T</code>

最终结果:

extension UIViewController {
    func instantiateVC<T: UIViewController>(type: T.Type) -> T? {
        let id = String(describing: T.self)
        return storyboard?.instantiateViewController(withIdentifier: id) as? T
    }
}

// how to use
guard let editVC = instantiateVC(type: EditVC.self) else { return }

前后对比:

// before
guard let editVC = storyboard?.instantiateViewController(withIdentifier: "EditVC") as? EditVC else { return }

// after
guard let editVC = instantiateVC(type: EditVC.self) else { return }

提醒:
这里我假装这个函数回避掉了直接使用字符串去传入 <code>Storyboard ID</code> 的风险,但可以这么做的前提是,这里的 <code>EditVC</code> 到 <code>"EditVC"</code> 可以直接字符串化。

如果你也要这么做的话,至少要保证你的类名的字符串化的结果和你的 <code>Storyboard ID</code> 是有固定关联的。比如 <code>EditVC</code> 对应 <code>"editvc"</code> 或 <code>"EDITVC"</code> 或 <code>"editVC"</code> (这样你只要修改字母大小写就可以了),而不是 <code>"abc123"</code> 这种随便写的东西。

相关文章

  • 【iOS 开发】用泛型简化 instantiateViewCon

    使用 storyboard 的时候,我们经常会写出下面这样的代码,用来跳转到其他页面 最多改成这样 实在是太冗长了...

  • Mach-O系列(四)__TEXT代码段

    在iOS8之后 借助Swift的泛型, 可以简化相关的代码

  • iOS 强大的泛型

    iOS 强大的泛型 iOS 强大的泛型

  • iOS 开发中的泛型

    在iOS开发中,泛型的使用,可以减少沟通的成本,明确类型。相信大家在开发中,或多或少,都接触或使用过泛型。比如在定...

  • Scala泛型

    泛型的意思是 泛指某种具体的数据类型 , 在Scala中, 泛型用 [数据类型] 表示. 在实际开发中, 泛...

  • 如何理解IOS中泛型

    在平时开发过程中,几乎所有人都接触过泛型这个概念,苹果从IOS9以后引入了泛型这个概念,从系统库到我们自定义泛型中...

  • Swift4 使用 "协议+泛型"简化UIT

    定义、注册、使用时我们会用到三次CellReuseldentifier,我们通过用协议和泛型简化UITableVi...

  • Java1.7和1.8新特性

    1.7新特性 switch支持string 创建泛型实例,可以通过类型推断简化代码,new后面的<>内不用再写泛型...

  • Java 泛型

    导读 移动开发知识体系总章(Java基础、Android、Flutter) 为什么会有泛型? 泛型类 泛型方法 泛...

  • iOS 强大的泛型

    文章围绕一下五点进行介绍: 泛型是什么为什么要用泛型泛型怎么用泛型进阶泛型的延伸使用 泛型(Generics)是什...

网友评论

    本文标题:【iOS 开发】用泛型简化 instantiateViewCon

    本文链接:https://www.haomeiwen.com/subject/ubbbuttx.html