1.參數(shù)標(biāo)簽
swift2.x版本第一個參數(shù)標(biāo)簽可以不用指定延旧,調(diào)用時谋国,不需要添加,swift3默認(rèn)會將第一個參數(shù)名作為參數(shù)標(biāo)簽迁沫,意味著不做改動很多調(diào)用都需要修改芦瘾。
// Swift 2
func handleError(error: NSError) { }
let error = NSError()
handleError(error) // Looks like Objective-C
// Swift 3
func handleError(error: NSError) { }
let error = NSError()
handleError(error: error)
可以這么做來解決這個問題:
// Swift 3
func handleError(_ error: NSError) { }
// ?? Notice the underscore!
let error = NSError()
handleError(error) // Same as in Swift 2
2.API改動
// swift2
NSBundle.mainBundle().infoDictionary
// swift3
Bundle.main.infoDictionary
// swift2
NSSearchPathDirectory.DocumentDirectory
NSSearchPathDomainMask.UserDomainMask
// swift3
FileManager.SearchPathDirectory.documentDirectory
FileManager.SearchPathDomainMask.userDomainMask
//
UIScreen.mainScreen()
UIScreen.main
//
NSFileManager.defaultManager()
FileManager.default
//
NSFileManager.defaultManager().fileExistsAtPath(path)
FileManager.default.fileExists(atPath: path)
3.Xcode8 Use Legacy Swift Language Version的錯誤解決
pod 使用了swift
庫,直接修改podfile
到新版本的三方庫集畅,執(zhí)行pod install
時提示多個target
的swift
版本不匹配近弟。
4.枚舉小寫開頭
// swift2
enum ActivityStatus { // 開關(guān)
case UnKnow
case OnSwitch
case OffSwitch
}
// swift3
enum ActivityStatus { // 開關(guān)
case unKnow
case onSwitch
case offSwitch
}
5.Any vs AnyObject
將項目里的 AnyObject 轉(zhuǎn)成 Any 可能是大家遇到的第一件適配大事。如何解釋這個變化呢挺智?在 Swift 3 之前祷愉,我們可以寫完一個項目都只用 AnyObject 來代表大多數(shù)實例,好像不用與 Any 類型打交道赦颇。但事實上谣辞,Any 和 AnyObject 是有明顯區(qū)別的,因為 Any 可以代表 struct沐扳、class泥从、func 等等幾乎所有類型,而 AnyObject 只能代表 class 生成的實例沪摄。
那為什么之前我們在 Swift 2 里可以用 [AnyObject] 聲明數(shù)組躯嫉,并且在里面放 Int纱烘、String 等 struct 類型呢?這是因為 Swift 2 中祈餐,會針對這些 Int擂啥、String 等 struct 進行一個 Implicit Bridging Conversions,在 Array 里插入他們時帆阳,編譯器會自動將其 bridge 到 Objective-C 的 NSNumber哺壶、NSString 等類型,這就是為什么我們聲明的 [AnyObject] 里可以放 struct 的原因蜒谤。
但在 Swift 3 當(dāng)中山宾,為了達成一個門真正的跨平臺語言,相關(guān)提案將 Implicit Bridging Conversions 給去掉了鳍徽。所以如果你要把 String 這個 struct 放進一個 [AnyObject] 里资锰,一定要 as NSString,這些轉(zhuǎn)換都需要顯示的進行了——畢竟 Linux 平臺默認(rèn)沒有 Objective-C runtime阶祭。這樣各平臺的表現(xiàn)更加一致绷杜。當(dāng)然這是其中一個目標(biāo),具體可見 0116-id-as-any和相關(guān)提案的討論濒募。
6. typealias Closure (閉包)
// swift2
public typealias URLRequestClosure = (response: URLResponse?, data: Data?, error: Error?) -> Void
func requestData(callback: @escaping URLRequestClosure) -> Void {
// do request and get result
callback(response: response, data: data, error: error)
}
// swift3
public typealias URLRequestClosure = (URLResponse?, Data?, Error?) -> Void
func requestData(callback: @escaping URLRequestClosure) -> Void {
// do request and get result
callback(response, data, error)
}
7.默認(rèn)參數(shù)
錯誤
ambiguous use of 'yy_setTextHighlight'
text.yy_setTextHighlight(range, color: UIColor.clear, backgroundColor: UIColor.clear, tapAction: { [weak self] (view: UIView, text: NSAttributedString, range: NSRange, rect: CGRect) in
^
__ObjC.NSMutableAttributedString:561:15: note: found this candidate
open func yy_setTextHighlight(_ range: NSRange, color: UIColor?, backgroundColor: UIColor?, userInfo: [AnyHashable : Any]? = nil, tapAction: __ObjC.YYTextAction?, longPressAction: __ObjC.YYTextAction? = nil)
^
__ObjC.NSMutableAttributedString:570:15: note: found this candidate
open func yy_setTextHighlight(_ range: NSRange, color: UIColor?, backgroundColor: UIColor?, tapAction: __ObjC.YYTextAction? = nil)
// swift2
text.yy_setTextHighlight(range, color: UIColor.clear, backgroundColor: UIColor.clear, tapAction: { [weak self] (view: UIView, text: NSAttributedString, range: NSRange, rect: CGRect) in
self?.showFormAffix(affixModel)
})
// swift3
text.yy_setTextHighlight(range, color: UIColor.clear, backgroundColor: UIColor.clear, tapAction: { [weak self] (view: UIView, text: NSAttributedString, range: NSRange, rect: CGRect) in
self?.showFormAffix(affixModel)
}, longPressAction: nil)
原因是系統(tǒng)將YYKit從OC轉(zhuǎn)換到swift時鞭盟,第一個方法存在默認(rèn)參數(shù)longPressAction = nil
,在swift3中調(diào)用方法時瑰剃,可以不寫默認(rèn)參數(shù)懊缺,直接調(diào)用第二個方法是系統(tǒng)不知道是要調(diào)用第二個方法,還是要調(diào)用第一個方法培他。
/**
Convenience method to set text highlight
@param range text range
@param color text color (pass nil to ignore)
@param backgroundColor text background color when highlight
@param userInfo user information dictionary (pass nil to ignore)
@param tapAction tap action when user tap the highlight (pass nil to ignore)
@param longPressAction long press action when user long press the highlight (pass nil to ignore)
*/
open func yy_setTextHighlight(_ range: NSRange, color: UIColor?, backgroundColor: UIColor?, userInfo: [AnyHashable : Any]? = nil, tapAction: YYText.YYTextAction?, longPressAction: YYText.YYTextAction? = nil)
/**
Convenience method to set text highlight
@param range text range
@param color text color (pass nil to ignore)
@param backgroundColor text background color when highlight
@param tapAction tap action when user tap the highlight (pass nil to ignore)
*/
open func yy_setTextHighlight(_ range: NSRange, color: UIColor?, backgroundColor: UIColor?, tapAction: YYText.YYTextAction? = nil)
8.GDC
swift3
Creating a concurrent queue
let concurrentQueue = DispatchQueue(label: "queuename", attributes: .concurrent)
concurrentQueue.sync {
}
Create a serial queue
let serialQueue = DispatchQueue(label: "queuename")
serialQueue.sync {
}
Get main queue asynchronously
DispatchQueue.main.async {
}
Get main queue synchronously
DispatchQueue.main.sync {
}
To get one of the background thread
DispatchQueue.global(attributes: .qosDefault).async {
}
To get one of the background thread
DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async {
}
DispatchQueue.global().async {
// qos' default value is ′DispatchQoS.QoSClass.default`
}
9.String vs NSString
// swift2
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
let str = (textField.text ?? "" as NSString).stringByReplacingCharactersInRange(range, withString: string)
return str.characters.count <= 11
}
// swift3
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let originalStr = (textField.text ?? "") as NSString
let str = originalStr.replacingCharacters(in: range, with: string)
return str.characters.count <= 11
}
10. 指針
// swift2
FMDBDatabaseTool.sharedInstance.dbQueue.inTransaction { db, rollback in
rollback?.memory = true
}
// swwift3
queue.inTransaction { db, rollback in
do {
try db!.executeUpdate("INSERT INTO myTable VALUES (?)", values: [1])
try db!.executeUpdate("INSERT INTO myTable VALUES (?)", values: [2])
try db!.executeUpdate("INSERT INTO myTable VALUES (?)", values: [3])
if whoopsSomethingWrongHappened {
rollback!.pointee = true
return
}
try db!.executeUpdate("INSERT INTO myTable VALUES (?)", values: [4])
} catch {
rollback!.pointee = true
print(error)
}
}
11.swiftLint
假如你使用了swiftLint等代碼風(fēng)格檢查工具鹃两,你最好暫時把它禁用掉,它以往的代碼風(fēng)格可能和swift3不符合舀凛,比如舊版swiftLint約定枚舉是大寫開頭俊扳,而swift3約定是小寫開頭。
12.類前綴
NSBundle -> Bundle
NSTimeInterval -> TimeInterval
NSURL -> URL
NSURLRequest/NSMutableURLRequest -> URLRequest
13. 可選類型比較
// FIXME: comparison operators with optionals were removed from the Swift Standard Libary.
// Consider refactoring the code to use the non-optional operators.
14. UIControlState
// swift2
button.setImage(UIImage(named: "btnBookDownload"), for: .Normal)
// swift3
button.setImage(UIImage(named: "btnBookDownload"), for: .normal)
button.setImage(UIImage(named: "btnBookDownload"), for: UIControlState())
15. NSNotification.Name
//swift2
// swift3
extension NSNotification {
public struct Name : RawRepresentable, Equatable, Hashable, Comparable {
public init(_ rawValue: String)
public init(rawValue: String)
}
}
// swift2
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(markDataIsDirty), name: MPJournalSubscribeChangedNotification, object: nil)
// swift3
NotificationCenter.default.addObserver(self, selector: #selector(markDataIsDirty), name: NSNotification.Name(rawValue: MPJournalSubscribeChangedNotification), object: nil)
16. leastNormalMagnitude
// swift2
CGFloat.min
// swift3
CGFloat.leastNormalMagnitude