iOS開發系列--Swift 3.0

来源:http://www.cnblogs.com/kenshincui/archive/2016/06/17/5594951.html
-Advertisement-
Play Games

從寫第一篇Swift文章的時候到現在Swift已經從1.2發展到了今天的3.0,這期間由於Swift目前還在發展階段並不能向下相容,因此第一篇文章中的部分代碼在當前的Xcode環境中已經無法運行。在WWDC16上Apple公佈了Swift3.0,從中可以看出Apple對Swift的重視,以及Swif... ...


概述

從寫第一篇Swift文章的時候到現在Swift已經從1.2發展到了今天的3.0,這期間由於Swift目前還在發展階段並不能向下相容,因此第一篇文章中的部分代碼在當前的Xcode環境中已經無法運行。在WWDC16上Apple公佈了Swift3.0,從中可以看出Apple對Swift的重視,以及Swift開源半年以來的進步。儘管對於開發人員來說Swift3.0的變化會令你的程式幾乎處處報錯,但是試想一下如果Apple沒有追求極致的精神又怎麼會做出如此多的更改。今天的文章將重點介紹:What's new in Swift 3.0?從Swift編譯器和標準庫兩個方面來說明從Swift3.0的變化。

編譯器和語法變化

函數或方法參數

  • 調用函數或方法時從第一個參數開始就必須指定參數名

在Swift的歷史版本中出現過在調用函數時不需要指定任何函數參數(或者從第二個參數開始指定參數名),在調用方法時則必須從第二個參數開始必須指定參數名等多種情況,而在Swift3.0中不管是函數還是方法都必須從第一個參數開始必須指定參數名(當然可以使用“_”明確指出調用時省略參數)。

// 從第一個參數就必須指定參數名,除非使用"_"明確指出省略參數
func sum(num1:Int,num2:Int)->Int{
    return num1 + num2
}

sum(num1: 1, num2: 2) // old: sum(1,2)或者sum(1, num2: 2)
  • 取消var參數
//func increase(var a:Int){
//    a += 1
//}
// 上面的代碼會報錯,可改寫成
func increase(a:Int){
    var a = a
    a += 1
}
  • inout參數修飾改放到類型前
//func increase(inout a:Int) {
//    a += 1
//}
// 上面的代碼會報錯,可改為
func increase( a:inout Int) {
    a += 1
}

方法返回值

Swift 3.0 中方法的返回值必須有接收否則會報警告,當然其實主要目的是為了避免開發人員忘記接收返回值的情況,但是有些情況下確實不需要使用返回值可以使用"_"接收來忽略返回值。當然你也可以增加@discardableResult聲明,告訴編譯器此方法可以不用接收返回值。

struct Caculator {
    func sum(a:Int,b:Int) -> Int {
        return a + b
    }
    
    @discardableResult
    func func1(a:Int,b:Int) ->Int {
        return a - b + 1
    }
}
let ca = Caculator()
ca.sum(a: 1, b: 2) // 此處會警告,因為方法有返回值但是沒有接收
let _ = ca.sum(a: 1, b: 2) // 使用"_"接收無用返回值
ca.func1(a: 1, b: 2) // 由於func1添加了@discardableResult聲明,即使不接收返回值也不會警告

可選類型

Swift3.0對於可選類型控制更加嚴謹,隱式可選類型和其他類型的運算之後獲得的是可選類型而不是隱式可選類型。

let a:Int! = 1
let b = a + 1 // 此時強制解包,b是Int型
let c = a // 註意此時c是Int? 在之前的Swift版本中c是Int!

Selector的變化

Selector的改變其實從1.0到3.0經歷了多次變化,從最早的@Selector("method:")到現在的#selector(method(param1:))可以說經歷了多次修改,好在它變得越來越好,畢竟字元串操作對於語法檢查來說是很無助的。

class MyClass {
    @objc func sum(a:Int,b:Int) -> Int {
        return a + b
    }
    
    func func1(){
        let _ = #selector(sum(a:b:))
    }
}

// old: Swift 2.2
//class MyClass {
//    @objc func sum(a:Int,b:Int) -> Int {
//        return a + b
//    }
//    
//    func func1(){
//        let _ = #selector(sum(_:b:))
//    }
//}

協議中的可選方法

在Swift3.0之前如果要定義協議中可選方法,只需要給協議加上@objc之後方法使用optional修飾就可以了但是Swift3.0中除了協議需要@objc修飾可選方法也必須使用@objc來修飾

@objc protocol MyProtocol {
    @objc optional func func1() //old: optional func func1()
    func func2()
}

取消++、--操作符

var d = 1
d++ //報錯,可以改寫成 d += 1 或者 d = d + 1

取消C風格for迴圈

//for var i = 0 ;i < 10 ; i += 1 {
//    debugPrint(i)
//}
// 上面的代碼會報錯,可改寫成如下代碼
for i in 0  ..< 10  {
    debugPrint(i)
}

SDK類庫變化

大家都知道Swift誕生在Objective-C已經發展的相當成熟的情況下,為了保證ObjC開發人員順利過渡到Swift,也因為Swift處於初級階段,很多類庫和方法命名都儘量和ObjC保持一致,在使用Swift開發iOS應用中處處可以看到ObjC的影子。但是作為一門Modern語言Swift還是做出了改變,從中可以看出日後Swift將徹底擺脫ObjC的影子。這其中包括重新導入Foundation消除類型首碼、方法名去重、函數和方法去C風格等等。

命名

// 1.去掉首碼
let url1 = URL(string: "www.cmjstudio.com")
let isFileURL = url1?.isFileURL //old:url1.fileURL ,現在更加註重語意
let data1 = Data() //NSData

// 2.方法名使用動詞,其他名詞、介詞等作為參數或移除
var array1 = [1,2,3]
array1.append(contentsOf: [4,5,6]) // old:array1.appendContentsOf([4,5,6])
array1.remove(at: 0) // old:array1.removeAtIndex(0)

// 3.不引起歧義的情況下儘量消除重覆
let color1 = UIColor.red() // old:var color1 = UIColor.redColor()

// 4.枚舉成員首字母變成小寫
let label1 = UILabel()
label1.textAlignment = .center // old:label1.textAlignment = .center

// 5.按鈕的Normal狀態去掉
let btn1 = UIButton()
btn1.setTitle("hello", for: UIControlState()) // 相當於Normal狀態

去C風格

Swift發展初期很多類庫的引入依然保持的ObjC風格,但是ObjC由於根出C語言,因此很多操作其實並不是對象和方法操作而是C語言的函數形式。到了Swift3.0之後這一現狀將發生變化,全局函數將會變成某些類型的方法;某些常量定義將以某個枚舉類型的成員來表示。

let rect1 = CGRect(x: 0, y: 0, width: 100, height: 100)
// 下麵的代碼將要報錯,3.0完全廢除這種類C的風格
//let rect1 = CGRectMake(0, 0, 100, 100)

if let context1 = UIGraphicsGetCurrentContext() {
    CGContext.fillPath(context1) // old:CGContextFillPath(context1!)
}

// GCD的改變
let queue = DispatchQueue(label: "myqueue")
queue.async {
    debugPrint("hello world!")
}
// old:
//let queue = dispatch_queue_create("myqueue", nil)
//dispatch_async(queue) {
//    debugPrint("hello world!")
//}

// 相關常量定義被移到枚舉內部
NotificationCenter.defaultCenter().addObserver(self, selector: #selector(userDefaultChange()), name: UserDefaults.didChangeNotification, object: nil)
//old:NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(userDefaultChange()), name: NSUserDefaultsDidChangeNotification, object: nil)

集合API的變化

let array1 = [1,2,3]
let next = array1.index(after: 0)  // old:let start = array1.startIndex let next = start.successor()
let first = array1.first { (element) -> Bool in // 增加新的方法
    element > 1
}

let r = Range(0..<3) //old: let _ = NSRange(location: 0, length: 3)

// 下麵的代碼必須在控制器中執行,用於遍歷當前view及其父視圖
for subview in sequence(first: self.view, next: { $0?.superview }){
    debugPrint(subview)
}

新的浮點協議

Float、Double、CGFloat使用了新的協議,提供了提供 IEEE-754標準的屬性和方法。

let a = 2 * Float.pi // old: let a = 2 * M_PI
let b = 2.0 * .pi // 註意前面是浮點型,後面可以省略Float

當然Swift3.0中還有一些其他的不常用變化,如果感興趣可以訪問Swift Proposals

從Swift2.2遷移到Swift3.0

可以看出如果要更新到Swift3.0現有項目需要作出大量修改,經過使用之前開源項目TagEditor進行測試,區區十個類文件就出現了一百多個錯誤,不過好在Xcode 8已經提供了很好用的遷移工具(Xcode:Editor - Convert - To Current Swift Syntax),經過遷移工具轉化後僅僅發現兩處錯誤需要手動修正。在使用這個工具的時候大家會看到如下界面:

Swift 2.3?沒錯Swift2.2和Swift 3.0中間還有個Swift 2.3,Apple也解釋了什麼是Swift 2.3,其實就是Swift 2.2 + New SDKs。之所以如此是因為Xcode 8目前還是beta版,使用Swift 3.0進行開發的應用還不能提交App Store,因此在Swift 2.2基礎上使用新的SDK開發還是有存在必要的。

總結

Swift的每次變化由於對之前的版本乃至上一個版本都不相容造成每次Swift的升級都顯得比較虐心,但是事實上這也是Swift的重大進步。記得之前曾有傳聞說Swift3.0的語法和API都會穩定並且向上相容,但是不久這個消息就破滅了,WWDC上官方也再次證實這個希望可能要到4.0才能實現。但是試想一下:Apple在很短的時間內就固話API對於Swift的發展真的是好事嗎?畢竟新特性的加入、更好的語法優化才能讓Swift越來越好!總的來說,如果應用要升級到Swift3.0可能要做不同程度的修改,但是這種改動僅僅是語法和SDK的變動並不會消耗太多的工作量,更何況Apple提供了遷移工具。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 先來個相容性說明,洗洗腦: div{transform:rotate(7deg);-ms-transform:rotate(7deg); /* IE 9 */-moz-transform:rotate(7deg); /* Firefox */-webkit-transform:rotate(7deg ...
  • 遞歸函數: function factorical(num){ if(num<=1){ return 1; } else{ return num*factorical(num-1); } } factorial(2)//2 這個遞歸函數就是用函數來調用函數本身,但是這樣真的好嗎,好 接下來看這裡 v ...
  • 從jQuery API 文檔中可以知道,jQuery自定義動畫的函數.animate( properties [, duration] [, easing] [, complete] )有四個參數: properties:一組包含作為動畫屬性和終值的樣式屬性和及其值的集合 duration(可選): ...
  • 還記得之前的javascript入門裡的講的confirm 消息對話框嗎?不記得也沒關係,我們先來回顧一下,然後在詳細講它。 複習: confirm 消息對話框通常用於允許用戶做選擇的動作,如:“你對嗎?”等。彈出對話框(包括一個確定按鈕和一個取消按鈕)。 語法: 參數說明: str:在消息對話框中 ...
  • 當初始化SpaceShip原型時,我們尚未創建任何能作為第一個參數來傳遞的場景。並且SpaceShip的原型加入到場景的註冊表中,而這絕不是我們想做的。這是一種使用子類時常用的方法。應當僅僅在子類構造函數中調用父類構造函數,而不是當創建子類原型時調用它。 一旦創建了SpaceShip的原型對象,我們... ...
  • 當頁面使用 UITabBarController + UINavigationController 框架的時候,當跳轉到詳情頁面的時候,如果 UITabBar 仍然存在的話就會造成邏輯混亂,用戶體驗也會下降,因此我們就有一個在詳情頁將 UITabBar 隱藏的需求,當然,在其他的一些情況也可能有隱藏 ...
  • 用類對象作為ArrayAdapter綁定的基本數據類型(和SimpleAdater效果類似) 一般ArrayAdapter綁定的基本數據類型是String,接下來介紹一下類對象作為基本數據類型; 首先,新建一個類News,這個類作為基本的數據類型 接下來先把listView的item的佈局確定下來, ...
  • 最近因為項目需要對聲音進行變聲,所以邊學習邊做,發現音頻的處理思路並不難,但是做起來還是有些繁瑣的(比預期的) 趁著腦子還發熱,趕緊把思路總結一下,記錄下來。 主要講三個部分 1,如何變聲2,安卓實現變聲3,ios實現變聲 1. 要想自己寫一個變聲的函數或者庫出來,談何容易,所以採用了大家普遍採用的 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...