一茧痕、Swift趨勢(shì)
雖然還處于過(guò)渡時(shí)期句葵,但趨勢(shì)很明朗了,Swift 必然會(huì)替代 Objective-C芬位,并且比想象中來(lái)得快∥揶郑現(xiàn)在就應(yīng)該做好準(zhǔn)備了。假如之前已經(jīng)掌握了 Objective-C昧碉,切換到 Swift 也不難英染。Swift 中很多概念在 Objective-C 中已經(jīng)存在。隨著時(shí)間推移被饿,Swift 在整個(gè) iOS/Mac 工程中占的代碼比例會(huì)越來(lái)越多四康,而 Objective-C 作為粘合層還是會(huì)存在。
二狭握、Swift優(yōu)缺點(diǎn)
用Swift的經(jīng)驗(yàn)尚淺闪金,所以都是一些比較淺薄的理解,后面有更深刻的理解再補(bǔ)上。
優(yōu)點(diǎn):
- 代碼簡(jiǎn)潔哎垦。類的聲明和實(shí)現(xiàn)在一個(gè)文件中囱嫩。
- 統(tǒng)一對(duì)屬性和方法的調(diào)用,都用.漏设。
- 如果不加額外的訪問(wèn)控制墨闲,所有的符號(hào)都是整個(gè)項(xiàng)目可見(jiàn),無(wú)需考慮頭文件的問(wèn)題郑口。
- 結(jié)合playground鸳碧,做到真正意義上的所見(jiàn)即所得
- 字符串處理太方便了。
//字符串比較和拼接實(shí)在是太方便了
let foo = "abc"
let bar = "abc"
if foo == bar {
//blablabla
}
print("====\(foo)+\(bar)")
- 語(yǔ)言上支持延遲加載犬性。
lazy var imageView : UIImageView = {
var imageView = UIImageView(image: UIImage(named: "empty_hint"))
imageView.contentMode = .ScaleAspectFit
return imageView
}()
lazy var infoLabel : UILabel = {
var infoLabel = UILabel()
infoLabel.lineBreakMode = .ByWordWrapping //支持換行
infoLabel.numberOfLines = 0
return infoLabel
}()
lazy var button : UIButton = {
var button = UIButton()
button.titleLabel?.font = UIFont.systemFontOfSize(15)
button.setTitleColor(UIColor.darkGrayColor(), forState: .Normal)
button.setBackgroundImage(UIImage(named: "buy_instance_hint_button"), forState: .Normal)
button.hidden = true
return button
}()
- 多返回值瞻离。比如下面這個(gè)函數(shù),如果使用Objective-C寫(xiě)還是比較麻煩的乒裆。
//將 "創(chuàng)建中&#FA8C35" 翻譯成對(duì)應(yīng)的 "(字符串對(duì)象, 顏色對(duì)象)"
func YWSTranslateRichText (str : String) -> (text : String, color : UIColor) {
let statusArray = str.componentsSeparatedByString("&")
if statusArray.count == 0 {
return ("", UIColor.lightGrayColor())
}
if statusArray.count == 1 {
return (statusArray[0], UIColor.lightGrayColor())
}
return (statusArray[0], UIColor.fromHexString(statusArray[1]))
}
//使用方式如下
let (text, color) = YWSTranslateRichText(instanceStatusConf)
- 支持字符串作為枚舉值套利。
enum YWSECSInstanceStatus : String {
case Starting = "Starting"
case Running = "Running"
case Stopping = "Stopping"
case Stopped = "Stopped"
}
//使用方法
cell.ECSInstanceStatus = YWSECSInstanceStatus(rawValue: instanceStatus!)
//轉(zhuǎn)換成字符串
textDetailLabel.text = YWSECSInstanceStatus.Starting.rawValue
缺點(diǎn):
- Swift靈活性非常大,既能用OP缸兔,又能用OO日裙,語(yǔ)法寫(xiě)法還比較多樣化,所以團(tuán)隊(duì)項(xiàng)目合作中必須注意惰蜜,盡量能統(tǒng)一風(fēng)格昂拂,否則會(huì)導(dǎo)致一片亂~
- Optional讓人頭疼,大量的?和!抛猖,沒(méi)處理好很容易導(dǎo)致崩潰格侯。
- 強(qiáng)類型和Optional,給JSON解析帶來(lái)了災(zāi)難财著。
- 目前Xcode不支持對(duì)Swift寫(xiě)的代碼做重構(gòu)联四。
- Build Settings里面設(shè)置Treat Warnings as Errors對(duì)Swift代碼無(wú)效。
- Swift不支持宏撑教,OC里面比較常用的宏朝墩,比如下面這個(gè)UIColorFromRGB就沒(méi)法用了。
#define UIColorFromRGB(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]
- 不支持與C++混編伟姐,必須通過(guò)OC包一下C++的接口收苏,Swift才能使用。使用一些跨端的C++庫(kù)(OpenGL愤兵、全文搜索鹿霸、網(wǎng)絡(luò)底層等)比較麻煩。
- Swift的錯(cuò)誤信息非常不準(zhǔn)確秆乳,難以準(zhǔn)確定位
坑
- 用private修飾的類懦鼠,如果使用KVC來(lái)給屬性設(shè)置值钻哩,編譯不會(huì)報(bào)錯(cuò),運(yùn)行時(shí)也不會(huì)報(bào)錯(cuò)肛冶,但就是設(shè)置不上街氢。去掉private就好了。
- Swift和OC混著寫(xiě)的時(shí)候睦袖,有時(shí)候會(huì)出現(xiàn)OC的類在CloudConsoleApp-Bridging-Header.h里面提供給Swift使用阳仔,但是這個(gè)類又需要引入CloudConsoleApp-Swift.h使用Swift的一些功能,這樣就循環(huán)包含了扣泊,沒(méi)法玩下去了。
Swift代碼規(guī)范指南
- Swift Style Guide | 中文版
- 推薦閱讀官方的 API Design Guidelines
三嘶摊、資源整理
1.蘋(píng)果官方資源
-
蘋(píng)果官方為開(kāi)發(fā)者提供的Swfit學(xué)習(xí)資源:https://developer.apple.com/swift/resources/
-
Swfit的官方網(wǎng)站:https://swift.org
這里會(huì)介紹Swift的開(kāi)源階段成果和一些使用指導(dǎo),Swift的官方博客和Swift的一些動(dòng)向信息可以在這里看到
-
Github上的官方資源是swift-evolution
可以在這個(gè)庫(kù)里看到Swift的最新進(jìn)度。因?yàn)镾wift是一門(mén)開(kāi)源的語(yǔ)言叶堆,你可以在這里按照一定格式提出改進(jìn)的建議阱飘。
2. 第三方資源
這份指南匯集了Swift語(yǔ)言主流學(xué)習(xí)資源,并以開(kāi)發(fā)者的視角整理編排虱颗。http://dev.swiftguide.cn
這個(gè)倉(cāng)庫(kù)“匯集了Swift語(yǔ)言主流學(xué)習(xí)資源沥匈,并以開(kāi)發(fā)者的視角整理編排”。不得不說(shuō)整理的非常的用心忘渔,也很全面高帖。美中不足的是對(duì)于一個(gè)剛?cè)腴T(mén)的開(kāi)發(fā)者忽然看到收集的這么多資源可能會(huì)不知從何下手。需要好好找出一些適合自己的資源畦粮。
從開(kāi)發(fā)者角度介紹被廣泛運(yùn)用于實(shí)際Swift項(xiàng)目中的開(kāi)源庫(kù)散址。
這個(gè)倉(cāng)庫(kù)篩選了被廣泛應(yīng)用在Swift項(xiàng)目中的優(yōu)質(zhì)開(kāi)源庫(kù)。并且嘗試整理一些這些流行的庫(kù)的相關(guān)資源宣赔。如果你打算用Swift開(kāi)發(fā)一個(gè)實(shí)際項(xiàng)目预麸,希望這個(gè)倉(cāng)庫(kù)里收集的庫(kù)會(huì)對(duì)你有參考意義。
- 還有一個(gè)值得一提的是SwiftGG翻譯組:http://swift.gg 儒将。定期會(huì)翻譯Swift的相關(guān)文章吏祸,對(duì)于日常的學(xué)習(xí)精進(jìn)也很有幫助。
視頻
- 斯坦福課程Stanford University: Developing iOS 8 Apps with Swift(中文字幕版 By @網(wǎng)易公開(kāi)課)
書(shū)籍
推薦objccn出版的幾本書(shū):《Swift開(kāi)發(fā)者必備Tips》钩蚊、《函數(shù)式Swift》贡翘、《Swift進(jìn)階》。這幾本書(shū)都很有很高的質(zhì)量两疚,對(duì)于提高對(duì)Swift的掌握很有幫助床估。
優(yōu)秀Swift開(kāi)發(fā)者推薦
如果你還使用微博的話我有幾個(gè)優(yōu)秀的Swift開(kāi)發(fā)者推薦給你:
@StackOverflowError,被apple多次推薦的pin的開(kāi)發(fā)者诱渤。知乎專欄地址:https://zhuanlan.zhihu.com/cocoanotes
@an00na丐巫,微博著名第三方客戶端墨客開(kāi)發(fā)者。
@圖拉鼎,獨(dú)立開(kāi)發(fā)者递胧。iOS 作品:@奇點(diǎn)微博客戶端碑韵。
@沒(méi)故事的卓同學(xué)
優(yōu)秀網(wǎng)站推薦
- 輔助將舊的
Objective-C
代碼轉(zhuǎn)成Swift
Swiftify | Objective-C to Swift Converter
-
swiftmi
致力于打造一個(gè)國(guó)內(nèi)專業(yè)的Apple Swift交流和分享地方
四、項(xiàng)目實(shí)戰(zhàn)之混編
簡(jiǎn)介
-
混編無(wú)非兩種情況:
- 在Objective - C工程或者文件使用Swift的文件
- 在Swift工程或者文件使用Objective - C文件
-
在混編的過(guò)程中最重要的兩個(gè)文件:
橋接文件:
橋接文件ProjectName-Bridging-Header.h
缎脾,在首次創(chuàng)建其他文件的時(shí)候祝闻,會(huì)自動(dòng)生成。如果不小心刪除后遗菠,也可以手動(dòng)添加联喘,不過(guò)名字必須是工程名-Bridging-Header.h
,如果名字記不清也可以自己新建Header file后辙纬,在Targets-->Build Settings-->Swift Compiler - General-->Objective-C Bridging Header
配置文件路徑豁遭,這個(gè)文件主要是Swift使用OC類時(shí)使用。Objective-C Generated Interface Header Name
文件
這個(gè)文件是混編時(shí)贺拣,系統(tǒng)生成的Swift文件對(duì)應(yīng)的Objective-C的頭文件蓖谢,具體可以在Targets-->Build Settings-->Swift Compiler - General-->Objective-C Generated Interface Header Name
進(jìn)行配置,默認(rèn)文件名是工程名-Swift.h
譬涡,一般不做改動(dòng)闪幽。
使用
- Swift使用Objective-C
這種情況占絕大多數(shù)。只需要在ProjectName-Bridging-Header.h
這個(gè)頭文件中包含相關(guān)的頭文件就行涡匀。
pod組件另外一種引入的方式是通過(guò)#import引入盯腌。
比如SDWebImage可以通過(guò)下面兩種方式引入。
//在Bridging頭文件包含下面這個(gè)頭文件
#import <SDWebImage/UIImageView+WebCache.h>
//另外一種辦法陨瘩,在Swift文件中引入腊嗡。
import SDWebImage
Objective-C寫(xiě)的類和方法都會(huì)被改成Swift的使用方式,下面是兩個(gè)很典型的例子拾酝。使用的時(shí)候需要嘗試一下才能找到翻譯的Swift方法燕少。
//Objective-C
titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
titleLabel.numberOfLines = 0;
//Swift
cell.nameLabel?.lineBreakMode = .ByWordWrapping //全寫(xiě)是 NSLineBreakMode.ByWordWrapping
cell.nameLabel?.numberOfLines = 0
//Objective-C
UIImage *image = [UIImage imageNamed:@"abc"];
//Swift
let image = UIImage(named: "abc")
- Objective-C使用Swift
當(dāng)在OC文件中調(diào)用Swift文件中的類的時(shí)候,首先在OC文件中要加上 #import "ProjectName-swift.h"
這個(gè)文件雖然在工程中看不到蒿囤,但是它真實(shí)存在客们,編譯后,你可以按住Command+單擊該文件名材诽,就會(huì)看到具體生成的代碼底挫。
引入后,具體類的使用脸侥,直接按照OC的方式使用即可
混編注意事項(xiàng)
- 對(duì)于需要混編的Swift類添加@objc聲明或繼承NSObject或NSObject的子類
class TestClass
{
// 屬性
// 實(shí)現(xiàn)
}
如果要在Objective-C類中使用TestClass類建邓,應(yīng)當(dāng)使用@objc加以聲明,或者將TestClass繼承自NSObject或NSObject的子類睁枕,否則官边,引入ProductName-Swift.h之后沸手,程序找不到對(duì)應(yīng)類。
使用第三方Framework
設(shè)置: target-->build setting -->Packaging -->Defines Module為 “Yes”注簿;
然后契吉,配置文件Target -> Build Phases -> Link Binary,添加要導(dǎo)入的Framework诡渴;
最后捐晶,還是要配置橋接文件,比如要使用 abc-lib.framework庫(kù)中的 abc.h 就要這樣配置:#import"abc-lib/abc.h";
Subclass子類問(wèn)題對(duì)于自定義的類而言妄辩,Objective-C的類惑灵,不能繼承自Swift的類,即要混編的OC類不能是Swift類的子類眼耀。反過(guò)來(lái)泣棋,需要混編的Swift類可以繼承自O(shè)C的類。 注解
OC宏文件
如Swift文件要使用OC中定義的宏畔塔,只能使用常量簡(jiǎn)單宏文件。
- Swift中使用OC的block
Swift 2.* :Swift中使用閉包Closure
不能使用Block作為屬性進(jìn)行傳值鸯屿,必須是初始化方法或函數(shù)澈吨。
Objective-C文件中:
typedef void (^Myblock)(NSString *arg);
@interface FirViewController : UIViewController
@property (copy, nonatomic) Myblock myBlock;
//Swift 2.*版本,這種作為公共參數(shù)的形式寄摆,如果在Swift類中去回調(diào)的話谅辣,是有問(wèn)題的。提示沒(méi)有初始化方法婶恼,所以使用下面的以Block為參數(shù)的方法
- (void)transValue:(Myblock) block
@end
下面是.m文件
- (void)transValue:(Myblock)block{
if (block) {
block(@"firBack");
}
}
在Swift文件回調(diào):
@IBAction func goFirstAction(sender: AnyObject) {
let firVC:FirViewController = FirViewController()
firVC. transValue { ( arg:String !) -> Void in
self.aBtn?.setTitle(arg, forState: UIControlState.Normal)
}
self.navigationController?.pushViewController(firVC, animated: true)
}
經(jīng)測(cè)試現(xiàn)在swift版本已經(jīng)支持
firVC?.myBlock = { (arg) -> Void in
//....
}
五桑阶、問(wèn)題解答
1. 那是不是 Objective-C 就不需要學(xué)習(xí)呢?
并非如此勾邦。Swift 還沒(méi)有很好地解決好跟 C 和 C++ 混編的問(wèn)題蚣录。很多項(xiàng)目底層核心庫(kù)會(huì)采用 C/C++,界面和大部分邏輯采用 Swift 編寫(xiě)眷篇,需要 Objective-C 作為粘合層萎河。另外還存留很多庫(kù)是用 Objective-C 編寫(xiě)的,使用這些庫(kù)需要一定 Objective-C 知識(shí)蕉饼。
2. 為什么要選擇swift虐杯?
很多人現(xiàn)在還沒(méi)有學(xué)習(xí) Swift, 覺(jué)得它沒(méi)有什么優(yōu)點(diǎn),只是一個(gè)語(yǔ)言大雜燴昧港。只是等你真正使用 Swift 編寫(xiě)一兩個(gè)項(xiàng)目擎椰,就回不了頭。Swift 有些簡(jiǎn)便快速的寫(xiě)法创肥,在 Objective-C 中是沒(méi)有辦法做到的达舒。并且 Swift 的一些語(yǔ)言特性避免了很多 Objective-C 的坑值朋。使用 Swift 編寫(xiě)的任何功能,使用 Objective-C 也可以做到休弃,但是會(huì)麻煩得多吞歼。而假如太麻煩的話,明知道是好的塔猾,也不會(huì)去做篙骡。
很多事情,你還沒(méi)有見(jiàn)識(shí)過(guò)的時(shí)候丈甸,會(huì)覺(jué)得不需要糯俗。但等你真正接觸過(guò)了,就難以忍受再次失去了睦擂。比如幾年前項(xiàng)目還沒(méi)有采用 ARC〉孟妫現(xiàn)在看來(lái)假如沒(méi)有 ARC,代碼寫(xiě)起來(lái)太麻煩了顿仇,那時(shí)還沒(méi)有更先進(jìn)的寫(xiě)法淘正,根本不會(huì)有這樣的感覺(jué)。Swift 比 Objective-C 先進(jìn)【饰牛現(xiàn)在 Swift 還不穩(wěn)定鸿吆,語(yǔ)言、庫(kù)述呐、相關(guān)工具將會(huì)快速變動(dòng)惩淳,而這恰好說(shuō)明它在發(fā)展。
3. 公司項(xiàng)目開(kāi)發(fā)怎么選擇
很多大公司為求穩(wěn)乓搬,會(huì)仍然采用 Objective-C思犁。而個(gè)人開(kāi)發(fā)者和小團(tuán)隊(duì),新項(xiàng)目應(yīng)該直接采用 Swift 編寫(xiě)进肯,舊項(xiàng)目的新模塊也應(yīng)該使用 Swift 編寫(xiě)激蹲。這樣慢慢將整個(gè)語(yǔ)言重心從 Objective-C 切換到 Swift。Swift 的代碼更簡(jiǎn)潔江掩,開(kāi)發(fā)效率更高托呕。原有 Objective-C 項(xiàng)目,已經(jīng)使用 Objective-C 編寫(xiě)的比較穩(wěn)定的庫(kù)频敛,不需要也不建議要用 Swift 重新編寫(xiě)项郊,直接混編,讓它慢慢過(guò)渡就行了斟赚。大公司傾向于不犯錯(cuò)着降,求穩(wěn)。 個(gè)人開(kāi)發(fā)者和小團(tuán)隊(duì)拗军,求穩(wěn)一定不能跟大公司競(jìng)爭(zhēng)的任洞,更應(yīng)該求好求變蓄喇。