非常激動的和各位分享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都是非常好的東西,希望各位盡快用上,不然你要掉隊了