一、Swift趨勢
雖然還處于過渡時期,但趨勢很明朗了,Swift 必然會替代 Objective-C,并且比想象中來得快。現在就應該做好準備了。假如之前已經掌握了 Objective-C,切換到 Swift 也不難。Swift 中很多概念在 Objective-C 中已經存在。隨著時間推移,Swift 在整個 iOS/Mac 工程中占的代碼比例會越來越多,而 Objective-C 作為粘合層還是會存在。
二、Swift優缺點
用Swift的經驗尚淺,所以都是一些比較淺薄的理解,后面有更深刻的理解再補上。
優點:
- 代碼簡潔。類的聲明和實現在一個文件中。
- 統一對屬性和方法的調用,都用.。
- 如果不加額外的訪問控制,所有的符號都是整個項目可見,無需考慮頭文件的問題。
- 結合playground,做到真正意義上的所見即所得
- 字符串處理太方便了。
//字符串比較和拼接實在是太方便了
let foo = "abc"
let bar = "abc"
if foo == bar {
//blablabla
}
print("====\(foo)+\(bar)")
- 語言上支持延遲加載。
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
}()
- 多返回值。比如下面這個函數,如果使用Objective-C寫還是比較麻煩的。
//將 "創建中&#FA8C35" 翻譯成對應的 "(字符串對象, 顏色對象)"
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!)
//轉換成字符串
textDetailLabel.text = YWSECSInstanceStatus.Starting.rawValue
缺點:
- Swift靈活性非常大,既能用OP,又能用OO,語法寫法還比較多樣化,所以團隊項目合作中必須注意,盡量能統一風格,否則會導致一片亂~
- Optional讓人頭疼,大量的?和!,沒處理好很容易導致崩潰。
- 強類型和Optional,給JSON解析帶來了災難。
- 目前Xcode不支持對Swift寫的代碼做重構。
- Build Settings里面設置Treat Warnings as Errors對Swift代碼無效。
- Swift不支持宏,OC里面比較常用的宏,比如下面這個UIColorFromRGB就沒法用了。
#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++混編,必須通過OC包一下C++的接口,Swift才能使用。使用一些跨端的C++庫(OpenGL、全文搜索、網絡底層等)比較麻煩。
- Swift的錯誤信息非常不準確,難以準確定位
坑
- 用private修飾的類,如果使用KVC來給屬性設置值,編譯不會報錯,運行時也不會報錯,但就是設置不上。去掉private就好了。
- Swift和OC混著寫的時候,有時候會出現OC的類在CloudConsoleApp-Bridging-Header.h里面提供給Swift使用,但是這個類又需要引入CloudConsoleApp-Swift.h使用Swift的一些功能,這樣就循環包含了,沒法玩下去了。
Swift代碼規范指南
- Swift Style Guide | 中文版
- 推薦閱讀官方的 API Design Guidelines
三、資源整理
1.蘋果官方資源
-
蘋果官方為開發者提供的Swfit學習資源:https://developer.apple.com/swift/resources/
14998280519388.jpg
-
Swfit的官方網站:https://swift.org
這里會介紹Swift的開源階段成果和一些使用指導,Swift的官方博客和Swift的一些動向信息可以在這里看到
14998282182999.jpg -
Github上的官方資源是swift-evolution
可以在這個庫里看到Swift的最新進度。因為Swift是一門開源的語言,你可以在這里按照一定格式提出改進的建議。
14998284728990.jpg
2. 第三方資源
這份指南匯集了Swift語言主流學習資源,并以開發者的視角整理編排。http://dev.swiftguide.cn
這個倉庫“匯集了Swift語言主流學習資源,并以開發者的視角整理編排”。不得不說整理的非常的用心,也很全面。美中不足的是對于一個剛入門的開發者忽然看到收集的這么多資源可能會不知從何下手。需要好好找出一些適合自己的資源。
從開發者角度介紹被廣泛運用于實際Swift項目中的開源庫。
這個倉庫篩選了被廣泛應用在Swift項目中的優質開源庫。并且嘗試整理一些這些流行的庫的相關資源。如果你打算用Swift開發一個實際項目,希望這個倉庫里收集的庫會對你有參考意義。
- 還有一個值得一提的是SwiftGG翻譯組:http://swift.gg 。定期會翻譯Swift的相關文章,對于日常的學習精進也很有幫助。
14998295823327.jpg
視頻
- 斯坦福課程Stanford University: Developing iOS 8 Apps with Swift(中文字幕版 By @網易公開課)
14998416372889.jpg
書籍
推薦objccn出版的幾本書:《Swift開發者必備Tips》、《函數式Swift》、《Swift進階》。這幾本書都很有很高的質量,對于提高對Swift的掌握很有幫助。
優秀Swift開發者推薦
如果你還使用微博的話我有幾個優秀的Swift開發者推薦給你:
@StackOverflowError,被apple多次推薦的pin的開發者。知乎專欄地址:https://zhuanlan.zhihu.com/cocoanotes
@an00na,微博著名第三方客戶端墨客開發者。
@圖拉鼎,獨立開發者。iOS 作品:@奇點微博客戶端。
@沒故事的卓同學
優秀網站推薦
- 輔助將舊的
Objective-C
代碼轉成Swift
Swiftify | Objective-C to Swift Converter
14998428932894.jpg -
swiftmi
致力于打造一個國內專業的Apple Swift交流和分享地方
14998450192866.jpg
四、項目實戰之混編
簡介
-
混編無非兩種情況:
- 在Objective - C工程或者文件使用Swift的文件
- 在Swift工程或者文件使用Objective - C文件
-
在混編的過程中最重要的兩個文件:
橋接文件:
橋接文件ProjectName-Bridging-Header.h
,在首次創建其他文件的時候,會自動生成。如果不小心刪除后,也可以手動添加,不過名字必須是工程名-Bridging-Header.h
,如果名字記不清也可以自己新建Header file后,在Targets-->Build Settings-->Swift Compiler - General-->Objective-C Bridging Header
配置文件路徑,這個文件主要是Swift使用OC類時使用。Objective-C Generated Interface Header Name
文件
這個文件是混編時,系統生成的Swift文件對應的Objective-C的頭文件,具體可以在Targets-->Build Settings-->Swift Compiler - General-->Objective-C Generated Interface Header Name
進行配置,默認文件名是工程名-Swift.h
,一般不做改動。
使用
- Swift使用Objective-C
這種情況占絕大多數。只需要在ProjectName-Bridging-Header.h
這個頭文件中包含相關的頭文件就行。
pod組件另外一種引入的方式是通過#import引入。
比如SDWebImage可以通過下面兩種方式引入。
//在Bridging頭文件包含下面這個頭文件
#import <SDWebImage/UIImageView+WebCache.h>
//另外一種辦法,在Swift文件中引入。
import SDWebImage
Objective-C寫的類和方法都會被改成Swift的使用方式,下面是兩個很典型的例子。使用的時候需要嘗試一下才能找到翻譯的Swift方法。
//Objective-C
titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
titleLabel.numberOfLines = 0;
//Swift
cell.nameLabel?.lineBreakMode = .ByWordWrapping //全寫是 NSLineBreakMode.ByWordWrapping
cell.nameLabel?.numberOfLines = 0
//Objective-C
UIImage *image = [UIImage imageNamed:@"abc"];
//Swift
let image = UIImage(named: "abc")
- Objective-C使用Swift
當在OC文件中調用Swift文件中的類的時候,首先在OC文件中要加上 #import "ProjectName-swift.h"
這個文件雖然在工程中看不到,但是它真實存在,編譯后,你可以按住Command+單擊該文件名,就會看到具體生成的代碼。
引入后,具體類的使用,直接按照OC的方式使用即可
混編注意事項
- 對于需要混編的Swift類添加@objc聲明或繼承NSObject或NSObject的子類
class TestClass
{
// 屬性
// 實現
}
如果要在Objective-C類中使用TestClass類,應當使用@objc加以聲明,或者將TestClass繼承自NSObject或NSObject的子類,否則,引入ProductName-Swift.h之后,程序找不到對應類。
使用第三方Framework
設置: target-->build setting -->Packaging -->Defines Module為 “Yes”;
然后,配置文件Target -> Build Phases -> Link Binary,添加要導入的Framework;
最后,還是要配置橋接文件,比如要使用 abc-lib.framework庫中的 abc.h 就要這樣配置:#import"abc-lib/abc.h";
Subclass子類問題對于自定義的類而言,Objective-C的類,不能繼承自Swift的類,即要混編的OC類不能是Swift類的子類。反過來,需要混編的Swift類可以繼承自OC的類。 注解
OC宏文件
如Swift文件要使用OC中定義的宏,只能使用常量簡單宏文件。
- Swift中使用OC的block
Swift 2.* :Swift中使用閉包Closure
不能使用Block作為屬性進行傳值,必須是初始化方法或函數。
Objective-C文件中:
typedef void (^Myblock)(NSString *arg);
@interface FirViewController : UIViewController
@property (copy, nonatomic) Myblock myBlock;
//Swift 2.*版本,這種作為公共參數的形式,如果在Swift類中去回調的話,是有問題的。提示沒有初始化方法,所以使用下面的以Block為參數的方法
- (void)transValue:(Myblock) block
@end
下面是.m文件
- (void)transValue:(Myblock)block{
if (block) {
block(@"firBack");
}
}
在Swift文件回調:
@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)
}
經測試現在swift版本已經支持
firVC?.myBlock = { (arg) -> Void in
//....
}
五、問題解答
1. 那是不是 Objective-C 就不需要學習呢?
并非如此。Swift 還沒有很好地解決好跟 C 和 C++ 混編的問題。很多項目底層核心庫會采用 C/C++,界面和大部分邏輯采用 Swift 編寫,需要 Objective-C 作為粘合層。另外還存留很多庫是用 Objective-C 編寫的,使用這些庫需要一定 Objective-C 知識。
2. 為什么要選擇swift?
很多人現在還沒有學習 Swift, 覺得它沒有什么優點,只是一個語言大雜燴。只是等你真正使用 Swift 編寫一兩個項目,就回不了頭。Swift 有些簡便快速的寫法,在 Objective-C 中是沒有辦法做到的。并且 Swift 的一些語言特性避免了很多 Objective-C 的坑。使用 Swift 編寫的任何功能,使用 Objective-C 也可以做到,但是會麻煩得多。而假如太麻煩的話,明知道是好的,也不會去做。
很多事情,你還沒有見識過的時候,會覺得不需要。但等你真正接觸過了,就難以忍受再次失去了。比如幾年前項目還沒有采用 ARC。現在看來假如沒有 ARC,代碼寫起來太麻煩了,那時還沒有更先進的寫法,根本不會有這樣的感覺。Swift 比 Objective-C 先進。現在 Swift 還不穩定,語言、庫、相關工具將會快速變動,而這恰好說明它在發展。
3. 公司項目開發怎么選擇
很多大公司為求穩,會仍然采用 Objective-C。而個人開發者和小團隊,新項目應該直接采用 Swift 編寫,舊項目的新模塊也應該使用 Swift 編寫。這樣慢慢將整個語言重心從 Objective-C 切換到 Swift。Swift 的代碼更簡潔,開發效率更高。原有 Objective-C 項目,已經使用 Objective-C 編寫的比較穩定的庫,不需要也不建議要用 Swift 重新編寫,直接混編,讓它慢慢過渡就行了。大公司傾向于不犯錯,求穩。 個人開發者和小團隊,求穩一定不能跟大公司競爭的,更應該求好求變。