在Swift中使用Storyboard和Segue时的依赖注入

在Swift中使用Storyboard和Segue时的依赖注入

Demo下载
我们都知道在使用Storyboard时,实现依赖注入总是有点不优雅,让我们先来看看在Objective-C时如何使用:

Objective-C

//In RJDemoViewController.m
- (void)setDependenciesViewModel:(RJDemoViewModel *)viewModel delegate:(id <RJDemoViewControllerDelegate>)delegate
{
    self.viewModel = viewModel;
    self.delegate = delegate;
}

- (void)assertDependencies
{
    // 依赖的对象
    NSParameterAssert(self.viewModel &&self.delegate);
}
 
- (void)viewDidLoad
{
    [super viewDidLoad];
    [self assertDependencies];
}

然后就可以在prepareForSegue中设置依赖:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:showDemoViewController]) {
        RJDemoViewController *viewController = segue.destinationViewController;
        NSParameterAssert([viewController isKindOfClass:[RJDemoViewController class]]);
        [viewController setDependenciesViewModel:[self viewModelForSelectedThing] delegate:self];
    }
}

至此,当所有的依赖一旦没有被注入,软件就会立刻奔溃,错误定位也变得十分地方便。
然后在Swift中有没有存在更Swift的方式来实现依赖注入呐?

Swift

首先定义一个协议(Protocol):

protocol Injectable {
    associatedtype InjectObject
    func inject(_: InjectObject)
    func assertDependencies()
}

注意func inject(_: InjectObject)由于ViewController依赖的对象有可能是Number,String等等各种类型,为了可读性,所以忽略了inject方法的参数名,由遵循该协议的ViewController去自由定义:

class RJDemoViewController: UIViewController, Injectable {
 
    @IBOutlet weak private var mainLabel: UILabel!
    
    private var mainText: String!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //由于mainText是String!类型,若没赋值,这里就会Crash
        assertDependencies()
       
        // 大胆地使用mainText
        mainLabel.text = mainText
    }
    
    //注: 这里参数名定义为text,提高了可读性
    func inject(text: String) {
        mainText = text
    }
    
    func assertDependencies() {
        assert(mainText != nil)
    }
}

至此,在prepareForSegue中,便可实现注入

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "showDemoViewController" {
            let vc = segue.destinationViewController as! RJDemoViewController
            vc.inject("myMainText")
        }
    }

Demo下载
参考资料:
www.natashatherobot.com

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

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,262评论 4 61
  • 1. 今天的心情:愉快 生气 焦虑 2. 今天的进步: (1)今天孩子折叠了一辆飞机说送给我,叫我放进口袋,我放进...
    Benz妈咪阅读 199评论 2 0
  • 第一次认识衡山还是2010年,那时因公务短驻长沙几个月,正值端午,几个朋友约着就近走走,选择去衡山转转。长...
    成梅阅读 406评论 0 0
  • 《原来如此》 ——如意 为什么生气, 灵魂向往自由, 不愿意被限制! 你招人不舒服, 人家也招你不舒服...
    axjl如意阅读 228评论 0 0
  • 一群观众能在电影院观片时情不自禁的落泪、欢呼和鼓掌,除非这部影片相当的感人!永远不要忘记中国人是内敛的! 记得儿时...
    老应杂谈阅读 639评论 0 2