Swift 3.0 項目升級實戰(zhàn)

  • dispatch_once方法廢棄,可以使用如下兩種方式實現(xiàn):

public extension DispatchQueue {
private static var _onceTracker = String
/**
Executes a block of code, associated with a unique token, only once. The code is thread safe and will
only execute the code once even in the presence of multithreaded calls.
- parameter token: A unique reverse DNS style name such as com.vectorform.<name> or a GUID
- parameter block: Block to execute once
*/
public class func once(token: String, block:()->Void) {
objc_sync_enter(self)
defer { objc_sync_exit(self) }
if _onceTracker.contains(token) {
return
}
_onceTracker.append(token)
block()
}
}

第二種方式是蘋果推薦的方式(xCode自動將swift升級時,幾乎所有的dispath_once方法都會自動轉(zhuǎn)換成下面這種形式),代碼如下:

var t: SomeObject?
private static var __once: () = {
//此處做一次性操作
t = SomeObject()
}()

如果僅僅是需要單例模式的話可以通過如下代碼實現(xiàn)(static let 標(biāo)記的常量,為線程安全的,并且是懶加載,只賦值一次):

class SingleInstanceTest {
static let sharesdInstance = SingleInstanceTest()
private override init() {
// 注冊通知等關(guān)初始化操作
}
}

  • CGSize、CGPoint、CGRect 的make方法取消,需要使用CGSize(width: 1, height: 1)等方式創(chuàng)建
  • 很多原來的方法如systemFontOfSize都將最后的單詞變?yōu)榉椒ǖ耐獠繀?shù)名:UIFont.systemFont(ofSize: kGlobalFontSize_H)
  • UIColor等類型的類方法都變?yōu)殪o態(tài)屬性:

UIColor.redColor() -> UIColor.redColor
UIColor.clearColor() -> UIColor.clearColor

  • 繪制直線等CoreGraphics操作由之前的CGPathMoveToPoint、CGPathAddLineToPoint變?yōu)閜ath.move、path.addLine等,參數(shù)不變(大多數(shù)CoreGraphics的方法調(diào)用都顯得更swift化,可以查看相關(guān)文檔)。
  • 如果方法帶有返回值,例如

func sum(a: Int , b: Int) -> Int {
return a + b
}

如果不需要返回值可以通過 _ = sum(a: 5 , b: 6)來避免警告。

  • String與NSString必須顯示轉(zhuǎn)換例如,如下代碼會報錯:

func say(a: NSString) {
print(a)
}
var d : String = "hello"
say(a: d)

此時需要將變量d顯式轉(zhuǎn)換為NSString

  • NSDateFormatter、NSNumberFormatter、NSBundle等被徹底廢棄,需要使用DateFormatter和NumberFormatter、Bundle等代替,同時蘋果推出Date、Data、Calendar等swift類型(去OC化正在緊張進(jìn)行中,如果蘋果推出新的swift類型可以替代OC,可能會將原OC類型禁用掉,那么為了以后swift升級降低代碼的修改量,建議使用swift的類型)。
  • GCD更swift化,swift3.0中可以使用DispatchQueue獲取主線程、global線程或者創(chuàng)建單獨的線程,線程任務(wù)的提交可以通過DispatchQueue的asyn、syn等(注意:通過指定線程優(yōu)先級獲取的global線程方法已經(jīng)將要廢棄,可以通過使用global(qos:_)->DispatchQueue創(chuàng)建)。
  • swift 3.0中對數(shù)組的操作例如:插入、刪除、判斷是否包含的相關(guān)方法更簡潔:insert(: , at:)、remove(at: )、contains(: )
  • swift 3.0中獲取類的名稱(類型)需要通過 type(of: _)方法獲得,如下代碼所示:

class Person {
class func className() -> String {
return String(describing: self)
}
func typeS () -> String {
return String(describing: type(of: self))
// type(of: _)相當(dāng)于dynamicType
}
func typeO () -> Person.Type {
let c = type(of: self)
return c
}
}
var c = Person().typeS()
var d = Person.className()
var o = String(describing: Person().typeO())

  • swift3.0 中 UIControl的狀態(tài)(Normal、Disable、Highlight等)被封裝到一個結(jié)構(gòu)體中,并且該結(jié)構(gòu)體實現(xiàn)了OptionSet協(xié)議,該協(xié)議用于掩碼運算(注意:xCode會自動將.normal狀態(tài)變?yōu)閁IControlState(),可以修改為.normal)。
  • swift3.0 的取余運算:在xcode轉(zhuǎn)換swift版本時,會將取余運算符% 變?yōu)閠runcatingRemainder(dividingby:_),進(jìn)入文檔看了一下swift3.0的標(biāo)準(zhǔn)庫中多了許多的算數(shù)方法。
  • swift3.0通知變更,通知中心由NSNotificationCenter 變?yōu)?NotificationCenter,并且post與addObject方法中的key參數(shù)由NSNotification.Name代替,變化如下所示:
// swift 2
NSNotificationCenter.defaultCenter().postNotificationName("kLogoutNotification", object: nil)
// swift 3
NotificationCenter.default.post(name: NSNotification.Name.init(rawValue: "kLogoutNotification"), object: nil)
  • swift 3.0方法外參的變化,第一個參數(shù)也需要指定一個外參數(shù)(外參數(shù)為調(diào)用處顯示的參數(shù),內(nèi)參數(shù)是在函數(shù)內(nèi)使用的參數(shù)),如果不指定外參數(shù),需要有通配符替代,代碼如下所示:

// swift 2 的寫法,方法第一個外參數(shù),可以不需要顯示給出
func Say(p: Int , two: Int , _ three: Int) {
print("(p)")
print("(two)")
print("(three)")
}
// swift 3 的寫法,必須顯示給出第一個參數(shù)的外參數(shù),否則編譯報錯
func Say(_ p: Int , two: Int , _ three: Int) {
print("(p)")
print("(two)") // 第二個參數(shù)two可同時做內(nèi)參數(shù)與外參數(shù)
print("(three)") // 通配符代替第三個參數(shù),調(diào)用處可以不顯示外參數(shù)
}
Say(p: 0, two: 1, 2) //

  • swift 3.0 枚舉的變化,xCode升級swift時,會將所有的枚舉類型的值得首字母變?yōu)樾懀ú粡娭?,最好還是按照這個規(guī)則進(jìn)行編碼),代碼如下:

enum SchoolRange: Int {
case default = 1
case province
case city
case nation
func title() -> String {
switch self {
case .province:
return "省級"
case .city :
return "市級"
case .nation:
return "國家級"
default:
return "縣級"
}
}
}

  • swift3.0中的泛型可以獲取OC中泛型的類型,如果在OC中使用了泛型,那么在swift與OC的混編中,swift可以推測泛型占位符的類型,如下代碼所示。
// OC 泛型定義
// OC 代碼
@interface Person<T>
{
    id _typeCode;
} 
- (T)typeCode;
@end
@interface Student 
- (Person<School>)typeCodeSchool;
@end
// swift 2.2
var s: Student = Student()
var c = s.typeCodeSchool() //c的類型為Person
// swift 3.0
var s: Student = Student()
var c = s.typeCodeSchool() //c的類型為   Person<School>
  • private 和 fileprivate:在swift3中private的作用域縮小了,僅能在當(dāng)前的大括號內(nèi)被訪問,而fileprivate僅能在當(dāng)前文件中被訪問,如下代碼所示
// swift 2中 同一文件可以訪問private標(biāo)記的變量
class Person {
    private var name: String!
}
class Student {
    func testPer(p: Person) {
        p.name = "Hello"   // swift 2中private標(biāo)記的變量,可以被同一文件內(nèi)的任何類、方法訪問
    }
}
// swift 3中private標(biāo)記的變量只能被{}中的方法等訪問
class Person {
    private var name: String!
    fileprivate var age: Int!
}
class Student {
    func testPer(p: Person) {
        p.age = 32  // swift3中fileprivate標(biāo)記的變量可以在本文件中的任何位置訪問
        p.name = "Hello"   // 此處編譯錯誤
    }
}
  • swift3.0中的Bool類型的變量名前都加上了is如isEnable、isHidden等
  • swift3.0中新增open關(guān)鍵字,被open標(biāo)記的變量可以被不同的module的類繼承、重寫,public標(biāo)記的變量或者類可以被當(dāng)前module的類繼承、重寫,默認(rèn)情況下internal不可以被繼承或者重寫。
  • swift3.0中的逃逸閉包,如果閉包被作為參數(shù)傳遞到函數(shù)時,該閉包不需要立即執(zhí)行而是需要等某些線程完成任務(wù)之后再執(zhí)行,那么需要在該閉包前加上@escaping,否則編譯器報錯。如下代碼所示:

//以下函數(shù)是當(dāng)動畫頁面動畫結(jié)束之后執(zhí)行一個閉包
func animationAfter(completion: @escaping () -> Void) {
UIView.animate(withDuration: 0.3, animations: {
// do some animation
}) { (isCom) in
completion()
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容