使用objection来模块化开发iOS项目

来源:互联网 发布:阿里云解析域名教程 编辑:程序博客网 时间:2024/06/05 00:58

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

假设有以下场景:ViewControllerA.view里有一个button,点击之后push一个ViewControllerB,最简单的写法类似这样:

- (void)viewDidLoad{    [super viewDidLoad];    UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];    button.frame = CGRectMake(100, 100, 100, 30);    [button setTitle:@"Button" forState:UIControlStateNormal];    [button addTarget:self action:@selector(buttonTapped) forControlEvents:UIControlEventTouchUpInside];    [self.view addSubview:button];}- (void)buttonTapped{    ViewControllerB *vc = [[ViewControllerB alloc] init];    [self.navigationController pushViewController:vc animated:YES];}

这样写的一个问题是,ViewControllerA需要import ViewControllerB,也就是对ViewControllerB产生了依赖。依赖的东西越多,维护起来就越麻烦,也容易出现循环依赖的问题,而objection正好可以处理这些问题。

实现方法是:先定义一个协议(protocol),然后通过objection来注册这个协议对应的class,需要的时候,可以获取该协议对应的object。对于使用方无需关心到底使用的是哪个Class,反正该有的方法、属性都有了(在协议中指定)。这样就去除了对某个特定Class的依赖。也就是通常所说的「面向接口编程」。

JSObjectionInjector *injector = [JSObjection defaultInjector]; // [1]UIViewController <ViewControllerAProtocol> *vc = [injector getObject:@protocol(ViewControllerAProtocol)]; // [2]vc.backgroundColor = [UIColor lightGrayColor]; // [3]UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:vc];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即可。

@interface ViewControllerAModule : JSObjectionModule@end@implementation ViewControllerAModule- (void)configure{    [self bindClass:[ViewControllerA class] toProtocol:@protocol(ViewControllerAProtocol)];}@end

绑定操作是在configure方法里进行的,这个方法在被添加到injector里时会被自动触发。

JSObjectionInjector *injector = [JSObjection defaultInjector]; // [1]injector = injector ? : [JSObjection createInjector]; // [2]injector = [injector withModule:[[ViewControllerAModule alloc] init]]; // [3][JSObjection setDefaultInjector:injector]; // [4]
  • [1] 获取默认的 injector
  • [2] 如果默认的 injector 不存在,就新建一个
  • [3] 往这个 injector 里注册我们的 Module
  • [4] 设置该 injector 为默认的 injector

这段代码可以直接放到 + (void)load里执行,这样就可以避免在AppDelegate里import各种Module。

因为我们无法直接获得对应的Class,所以必须要在协议里定义好对外暴露的方法和属性,然后该Class也要实现该协议。

@protocol ViewControllerAProtocol <NSObject>@property (nonatomic) NSUInteger currentIndex;@property (nonatomic) UIColor *backgroundColor;@end@interface ViewControllerA : UIViewController <ViewControllerAProtocol>@end

通过objection实现依赖注入后,就能更好地实现SRP(Single Responsibility Principle),代码更简洁,心情更舒畅,生活更美好。拿Pinterest来说,下面的页面就可以划分为3个Section。

各个Section可以由不同的人负责,然后串到一起就行,也能一定程度地避免MVC(Mess View Controller)的出现。

总体来说,这个lib还是挺靠谱的,已经维护了两年多,也有一些项目在用,对于提高开发成员的效率也会有不少的帮助,可以考虑尝试下。

---- update (2014-04-30) ----

写了个壁纸的demo,https://github.com/lzyy/bizhi


--EOF--


http://limboy.me/tech/2014/04/15/use-objection-to-decouple-ios-project.html

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 华为手机账户密码忘记了怎么办 QQ浏览器无法加载插件怎么办 电脑开了机黑屏怎么办 扫描仪打不开运单扫描怎么办 打印机不支持64位系统怎么办 xp系统dnf闪退怎么办 w10电脑所有程序都打不开怎么办 安卓手机太卡怎么办 系统装到f盘了怎么办 虚拟机占c盘内存怎么办 外机连无线虚拟机显示受限怎么办 使用msdn下载解压后怎么办 路由80端口被占用怎么办 c盘拒绝粘贴文件怎么办 oracle数据库密码忘了怎么办 电脑开机时不显示用户名怎么办? xp系统忘记开机密码怎么办 电脑开机密码忘了怎么办 c盘满了怎么办win10 win10电脑开机密码忘了怎么办 win10的开机密码忘了怎么办 u盘中了exe病毒怎么办 眼睛长个麦粒豆怎么办 苹果手机sdk授权失败怎么办 小米5王者荣耀卡怎么办 华为p9手机电池不耐用怎么办 华为g9青春版耗电快怎么办 华为手机摄像头坏了怎么办 华为p10摄像头玻璃划痕怎么办? 华为g9手机音量小怎么办 华为7pius太卡怎么办 华为畅享7plus卡怎么办 华为p9屏幕进水变颜色怎么办? 玩王者荣耀卡退怎么办 华为手机忘记开机密码怎么办 华为p9密码忘了怎么办 华为p9解锁密码忘了怎么办 华为手机不支持联通4g怎么办 酷派手机自动下载软件怎么办 小米5a不能开机怎么办 华为手机的视频找不到了怎么办