转自无网不剩的博客

objection 是一个轻量级的依赖注入框架,受Guice的启发,Google Wallet 也是使用的该项目。「依赖注入」是面向对象编程的一种设计模式,用来减少代码之间的耦合度。通常基于接口来实现,也就是说不需要new一个对象,而是通过相关的控制器来获取对象。2013年最火的PHP框架 laravel 就是其中的典型。

 
假设有以下场景:ViewControllerA.view里有一个button,点击之后push一个ViewControllerB,最简单的写法类似这样:
  1. - (void)viewDidLoad
  2. {
  3. [super viewDidLoad];
  4. UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
  5. button.frame = CGRectMake(100, 100, 100, 30);
  6. [button setTitle:@"Button" forState:UIControlStateNormal];
  7. [button addTarget:self action:@selector(buttonTapped) forControlEvents:UIControlEventTouchUpInside];
  8. [self.view addSubview:button];
  9. }
  10. - (void)buttonTapped
  11. {
  12. ViewControllerB *vc = [[ViewControllerB alloc] init];
  13. [self.navigationController pushViewController:vc animated:YES];
  14. }
这样写的一个问题是,ViewControllerA需要import ViewControllerB,也就是对ViewControllerB产生了依赖。依赖的东西越多,维护起来就越麻烦,也容易出现循环依赖的问题,而objection正好可以处理这些问题。
 
实现方法是:先定义一个协议(protocol),然后通过objection来注册这个协议对应的class,需要的时候,可以获取该协议对应的object。对于使用方无需关心到底使用的是哪个Class,反正该有的方法、属性都有了(在协议中指定)。这样就去除了对某个特定Class的依赖。也就是通常所说的「面向接口编程」。
  1. JSObjectionInjector *injector = [JSObjection defaultInjector]; // [1]
  2. UIViewController <ViewControllerAProtocol> *vc = [injector getObject:@protocol(ViewControllerAProtocol)]; // [2]
  3. vc.backgroundColor = [UIColor lightGrayColor]; // [3]
  4. UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:vc];
  5. self.window.rootViewController = nc;
[1] 获取默认的injector,这个injector已经注册过ViewControllerAProtocol了。
[2] 获取ViewControllerAProtocol对应的Object。
[3] 拿到VC后,设置它的某些属性,比如这里的backgroundColor,因为在ViewControllerAProtocol里有定义这个属性,所以不会有warning。
 
可以看到这里没有引用ViewControllerA。再来看看这个ViewControllerAProtocol是如何注册到injector中的,这里涉及到了Module,对Protocol的注册都是在Module中完成的。Module只要继承JSObjectionModule这个Class即可。
  1. @interface ViewControllerAModule : JSObjectionModule
  2. @end
  3. @implementation ViewControllerAModule
  4. - (void)configure
  5. {
  6. [self bindClass:[ViewControllerA class] toProtocol:@protocol(ViewControllerAProtocol)];
  7. }
  8. @end
 
绑定操作是在configure方法里进行的,这个方法在被添加到injector里时会被自动触发。
  1. JSObjectionInjector *injector = [JSObjection defaultInjector]; // [1]
  2. injector = injector ? : [JSObjection createInjector]; // [2]
  3. injector = [injector withModule:[[ViewControllerAModule alloc] init]]; // [3]
  4. [JSObjection setDefaultInjector:injector]; // [4]
[1] 获取默认的 injector
[2] 如果默认的 injector 不存在,就新建一个
[3] 往这个 injector 里注册我们的 Module
[4] 设置该 injector 为默认的 injector
 
这段代码可以直接放到 + (void)load里执行,这样就可以避免在AppDelegate里import各种Module。
 
因为我们无法直接获得对应的Class,所以必须要在协议里定义好对外暴露的方法和属性,然后该Class也要实现该协议。
  1. @protocol ViewControllerAProtocol <NSObject>
  2. @property (nonatomic) NSUInteger currentIndex;
  3. @property (nonatomic) UIColor *backgroundColor;
  4. @end
  5. @interface ViewControllerA : UIViewController <ViewControllerAProtocol>
  6. @end
 
通过objection实现依赖注入后,就能更好地实现SRP(Single Responsibility Principle),代码更简洁,心情更舒畅,生活更美好。拿Pinterest来说,下面的页面就可以划分为3个Section。
 
各个Section可以由不同的人负责,然后串到一起就行,也能一定程度地避免MVC(Mess View Controller)的出现。
 
总体来说,这个lib还是挺靠谱的,已经维护了两年多,也有一些项目在用,对于提高开发成员的效率也会有不少的帮助,可以考虑尝试下。

CocoaChina是全球最大的苹果开发中文社区,官方微信每日定时推送各种精彩的研发教程资源和工具,介绍app推广营销经验,最新企业招聘和外包信息,以及Cocos2d引擎、Cocos Studio开发工具包的最新动态及培训信息。关注微信可以第一时间了解最新产品和服务动态,微信在手,天下我有!

使用objection来模块化开发iOS项目的更多相关文章

  1. Swift开发iOS项目实战视频教程(一)---iOS真简单

    本课主要介绍iOS项目的创建.第一个iOS项目的开发.UILabel.UIButton的使用. 假设你看完此视频还认为iOS非常难,请你来找我! 本教程摒弃枯燥的语法和知识解说,全是有趣有料的项目实战 ...

  2. Swift开发iOS项目实战视频教程(二)---图片与动画

    本课主要介绍UIImageview.NSTimer的使用.并介绍了一种动画实现方式. 本教程摒弃枯燥的语法和知识解说.全是有趣有料的项目实战! 视频优酷链接:v.youku.com/v_show/id ...

  3. 使用Swift开发iOS项目、UI创建、方法调用

    //1.root控制器的创建        var rootCtrl =RootViewController()        var root:UINavigationController =UIN ...

  4. 10个Spring Boot快速开发的项目,接私活利器(快速、高效)

    本文为大家精选了 码云 上优秀的 Spring Boot 语言开源项目,涵盖了企业级系统框架.文件文档系统.秒杀系统.微服务化系统.后台管理系统等,希望能够给大家带来一点帮助:) 1.项目名称:分布式 ...

  5. Android模块化开发实践

    一.前言 随着业务的快速发展,现在的互联网App越来越大,为了提高团队开发效率,模块化开发已经成为主流的开发模式.正好最近完成了vivo官网App业务模块化改造的工作,所以本文就对模块化开发模式进行一 ...

  6. iOS关于模块化开发解决方案(纯干货)

    关于iOS模块化开发解决方案网上也有一些介绍,但真正落实在在具体的实例却很少看到,计划编写系统文章来介绍关于我对模块化解决方案的理解,里面会有包含到一些关于解耦.路由.封装.私有Pod管理等内容:并编 ...

  7. 基于CocoaPods的iOS项目模块化实践

    什么是CocoaPods? CocoaPods is a dependency manager for Swift and Objective-C Cocoa projects. It has ove ...

  8. iOS项目的目录结构和开发流程

    转自无网不剩的博客 网上相关的资源不多,开源的且质量还不错的iOS项目也是少之又少,最近正好跟同事合作了一个iOS项目,来说说自己的一些想法.   目录结构 AppDelegate Models Ma ...

  9. (转)iOS项目的目录结构和开发流程

    网上相关的资源不多,开源的且质量还不错的iOS项目也是少之又少,最近正好跟同事合作了一个iOS项目,来说说自己的一些想法. 目录结构 AppDelegate Models Macro General ...

随机推荐

  1. python 之 time模块、datetime模块(打印进度条)

    6.9 time 模块 方法 含义 备注 time.time() 时间戳 1561013092.997079 time.strftime('%Y-%m-%d %H:%M:%S %p') 结构化时间st ...

  2. 编译最新linux内核(version 4.4.2)

    环境:centos6.4 内核版本为2.6.32 目标:编译4.4.2内核,升级到 4.4.2 准备工作: 安装开发库和ncurses库 # yum groupinstall "Develo ...

  3. 支持通配符查询的k-gram索引

    k-gram索引的通配符查询处理技术称为k-gram索引. 一个k-gram代表由k个字符组成的序列.对于词项castle来说,cas.ast.stl都是3-gram.我们用特殊的字符$来标识词项的开 ...

  4. Continuous Integration

    https://dzone.com/articles/continuous-delivery-toolchain

  5. 黑马学习SpringMVC 基本开发步骤

  6. Maven - StackOverflowError

    问题与分析 今天发现服务器上的Jenkins在集成项目时报错,报错原因如下: error compiling: java.lang.StackOverflowError -> [Help 1] ...

  7. 题解 poj1845 Sumdiv (数论) (分治)

    传送门 大意:求A^B的所有因子之和,并对其取模 9901再输出 (这题又调了半天,把n和项数弄混了QAQ) 根据算数基本定理:A=(p1^k1)*(p2^k2)*(p3^k3)*...*(pn^kn ...

  8. WebApi迁移ASP.NET Core2.0

    WebApi迁移ASP.NET Core2.0 一步一步带你做WebApi迁移ASP.NET Core2.0   随着ASP.NET Core 2.0发布之后,原先运行在Windows IIS中的AS ...

  9. org.apache.ibatis.binding.BindingException【原因汇总】

    这个问题整整纠结了我四个多小时,心好累啊...不废话... 背景:Spring整合Mybatis 报错:org.apache.ibatis.binding.BindingException: Inva ...

  10. Ubuntu下安装nginx及使用

    首先介绍以下nginx.下图来自百科介绍:详细介绍地址:https://baike.baidu.com/item/nginx/3817705?fr=aladdin 在我们平时的开发娱乐中,也许并不会涉 ...