美文网首页iOS DeveloperiOS,object-c和swift开发
在Swift中使用Storyboard和Segue时的依赖注入

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

作者: rayjuneWu | 来源:发表于2016-05-11 11:31 被阅读535次

    在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

    相关文章

      网友评论

        本文标题:在Swift中使用Storyboard和Segue时的依赖注入

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