非常激动的和各位分享RFP的经验。目前国内使用swift开发实际项目的文章几乎还找不到,不用说ReactiveCocoa了。我打算把两个一起简单说一下。
MVC和MVVM的差异,我觉得对比实在是很细,重点是,MVVM的分割性更好,正交性强,而MVC在逻辑和试图代码方面经常混在一起,不能很好的模块化,以至于在多人开发的模式下,时不时出现逻辑混乱的情况。
另一个核心问题是,常规的编程思路在对象的依赖关系的维护方面基本无能为力。
我不想在一篇文章中扯一大把概念,MVVM的介绍和优点你可以自己去搜索。
原来兴致冲冲的百度了一下swift RFP/RAC/MVVM,没实质性内容,干脆自己写一篇。
就谈谈在swift中使用MVVM吧,你可以去我的
github仓库下载这里的完整代码.
RAC在object-c中的使用在github上有实例的。各位可以移步去看一下。
环境前提是你要有xcode6,pod管理器。这些工具你应该自己去找一下,当然你就用我的这个项目也行。
说一下集成步骤:
1.使用pod添加ReactiveCocoa到工程中,细节略。
2.打开编译xcworkspace,新建一个swift代码文件,在建立过程中,xcode会问你是不是要建立与object-c的混编中间头文件,选择是,并在这个头文件中加入RAC的头文件
#import <ReactiveCocoa/RACEXTScope.h>
#import <ReactiveCocoa/ReactiveCocoa.h>
以及你要使用的object-c的其他库的头文件
3.可以使用了,新建一个swift源文件,建立一个nib文件和它关联,然后设置一个button,代码类似这样:
@IOBullet button:UIButton = UIButton.buttonWithType(UIButtonType.Custom)
button.rac_signalForControlEvents(UIControlEvents.TouchUpInside)
.subscribeNext{
_ in
NSLog("按钮点击事件")
}
//加入到UI层去
测试可以使用RAC了。点击这个按钮,打印内容就出来了
4.在swift中使用类似object-c中的RAC(button, hidden) = RACObserve(button2, hidden)是会出错的。需要自己实现,object-c中的RAC()这个宏很讨厌,想搞懂的可以网上查,我也记不清了。好了,我们来解决这个问题。
新建一个swift源码,最好叫ReactiveCocoa.swift,加入下面的代码:
//
// ReactiveCocoa.swift
// XianRenZhang
//
// Created by kriswangw on 14/11/14.
// Copyright (c) 2014年 kriswangw. All rights reserved.
//
public struct RAC {
var target : NSObject!
var keyPath : String!
var nilValue : AnyObject!
init(_ target: NSObject!, _ keyPath: String, nilValue: AnyObject? = nil) {
self.target = target
self.keyPath = keyPath
self.nilValue = nilValue
}
func assignSignal(signal : RACSignal) {
signal.setKeyPath(self.keyPath, onObject: self.target, nilValue: self.nilValue)
}
}
public func RACObserve(target: NSObject!, keyPath: NSString) -> RACSignal {
return target.rac_valuesForKeyPath(keyPath, observer: target)
}
public func <= (rac:RAC, signal:RACSignal){
rac.assignSignal(signal)
}
public func >=( signal:RACSignal, rac:RAC){
rac.assignSignal(signal)
}
然后我只要改变tableView的hidden属性,scrollView的属性就会跟着改变了,不用再去维护两个变量。
//两个按钮的点击切换不同的内容。
self.changguan_btn.rac_signalForControlEvents(UIControlEvents.TouchUpInside)
.subscribeNext {
_ in
self.tableView.hidden = true;
}
self.zhanpin_btn.rac_signalForControlEvents(UIControlEvents.TouchUpInside)
.subscribeNext{
_ in
self.tableView.hidden = false;
}
RAC的函数思想使得代码服用行更强,可以让我们把按钮的控制写成逻辑算法,而不是一个一个的重复的回调事件函数,或者含有多个链接nib文件的函数(不好维护)。
//TODO,修改为对应的UIViewController.也有可能是同一个ViewController,但是参数不同
let ciqi_vc = UIViewController()
let yuqi_vc = UIViewController()
let huihua_vc = UIViewController()
let wenhuajiading_vc = UIViewController()
let zuke_vc = UIViewController()
let shufa_vc = UIViewController()
let qingtong_vc = UIViewController()
let keju_vc = UIViewController()
var btns2Actions: NSDictionary = [
"瓷器":[self.qiciBtn, ciqi_vc],
"玉器":[self.yuqiBtn, yuqi_vc],
"绘画":[self.huihuaBtn, huihua_vc],
"文化嘉定":[self.wenhuajiadingBtn, wenhuajiading_vc],
"竹刻":[self.zukeBtn, zuke_vc],
"书法":[self.shufaBtn, shufa_vc],
"青铜":[self.qingtongBtn, qingtong_vc],
"科举":[self.kejuBtn, keju_vc]]
//定制每个button事件跳转的视图控制器。
for (key : AnyObject, value : AnyObject ) in btns2Actions {
let array = value as NSArray;
let btn = array[0] as UIButton;
let vc:UIViewController = array[1] as UIViewController;
btn.rac_signalForControlEvents(UIControlEvents.TouchUpInside)
.subscribeNext { _ in
self.navigationController.pushViewController(vc, animated:false)
}
}
这段代码展示了使用抽象来统一所有事件响应的功能。每一个按钮对应的视图控制器都被绑定到一起了,如果新加入别的功能,代码仍然非常容易维护。所有功能相同的都放在了一起,约束性更强。
其他的RAC功能基本上默认就能使用,combineLatest也是可以直接使用的。记住swift中的所有方法调用都是"."下标符号,包括静态方法,init和隐式析够除外。
swift中没有#pragma宏,所以,它提供了这个注释风格(内置的)
// MARK:
, // TODO:
and // FIXME
可以达到和#pragma一样的效果
最后,swift和RFP都是非常好的东西,希望各位尽快用上,不然你要掉队了