Swift3.0 利用泛型设置基类属性的动态类型

Swift3.0 利用泛型设置基类属性的动态类型

原文链接
在MVVM架构的项目中,我们一般会写一个viewModel的基类和一个controller的基类,在controller的对象中持有viewModel,如下代码

class ViewModel{
    
}
class Controller {

    var viewModel:ViewModel
    
    init(viewModel:ViewModel) {
        self.viewModel = viewModel
    }
}

然后在每一个具体的页面上,都会写一个对应的viewModel和controller分别继承自上面两个基类

class Sub1ViewModel:ViewModel{
    
    let desc = "Sub1"

}
class Sub1Controller:Controller{
    
}

这时如果我想在Sub1Controller中访问Sub1ViewModel中的desc变量,只能在Sub1Controller中这样写

class Sub1Controller:Controller{
    var description{
        let viewModel = self.viewModel as! Sub1ViewModel
        return viewModel.desc
    }
}

由于Swift是强类型语言,不能像OC那样通过类型的强制转换来使基类的属性变成子类的类型,所以你每次使用基类的属性的时候都必须要用as强制转换成子类的类型之后才能访问子类的属性或者方法,当然你可以将这个强制转换包装成一个函数,或者提供另一个变量返回强制转换过的类型。

class Sub1Controller:Controller{
    var sub1ViewModel:Sub1ViewModel{
        return self.viewModel as! Sub1ViewModel
    }
    var description{
    //  let viewModel = self.viewModel as! Sub1ViewModel
        return self.sub1ViewModel.desc  // Or: return self.sub1ViewModel().desc
    }
    
    func sub1ViewModel() -> Sub1ViewModel{
        return self.viewModel as! Sub1ViewModel
    }
} 

但是这两种方法仍然不够优雅,产生了很多冗余的代码,笔者在实践中尝试着使用泛型来是基类的属性类型动态化,是代码看起来更优雅


class ViewModel{
}

class Controller<ModelType:ViewModel> {
    var viewModel:ModelType
    init(viewModel:ModelType) {
        self.viewModel = viewModel
    }
}

class Sub1ViewModel:ViewModel{  
    let desc = "Sub1"
}

class Sub1Controller:Controller<Sub1ViewModel>{
      var description{
        return self.viewModel.desc
    }
}

通过ModelType泛型类型,使得在Sub1Controller中直接通过viewModel就能访问到Sub1ViewModel的属性

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young阅读 4,024评论 1 10
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,288评论 19 139
  • 136.泛型 泛型代码让你可以写出灵活,可重用的函数和类型,它们可以使用任何类型,受你定义的需求的约束。你可以写出...
    无沣阅读 1,576评论 0 4
  • 1.0-基础部分 pragma mark:输出常量和变量 你可以用print(_:separator:termin...
    037e3257fa3b阅读 943评论 2 7
  • 我于杀戮之中盛放,亦如黎明之中的花朵。 我叫烬,我来自一个神秘的地方,你可以说我来自地狱,因为我的母亲在生我的时候...
    lhy123丶阅读 443评论 1 0