Xcode9和Swift4新特性

2021-02-23 樂Coding

XCode9新特性    1. 支持遠程調試    2. Xcode綁定Github帳號    3. 支持Swift類重命名    4. Swift低版本兼容    5. Main Thread Checker    6. 模擬器支持多開    7. 標示功能    8. 協議自動補全    9. 代碼段自動抽出函數    10. 自定義顏色名稱    11. Debug View Hierarchy可以顯示ViewController了    12.支持Markdown,可以在xcode中查閱、編輯markdown文件
Swift4更新    1. Extension可以訪問private的屬性    2. 類型和協議的組合類型    3. 新的Key Paths 語法    4. 下標支持泛型    5. 字符串        5.1 可以直接獲取字符串長度了        5.2 字符串獲取子串語法糖… One-sided Slicing        5.3 String增加了Collection的一些特性        5.4 多行字符串    6. 序列化的簡化    7. Dictionary and Set增強        7.1 通過Sequence初始化        7.2 字典過濾後類型不變        7.3 新增mapValues函數        7.4 字典支持默認值    8. MutableCollection新增swapAt(::) 用來交換兩個位置的值

上篇文章我們介紹了iOS11適配iPhoneX總結,這次分享下Xcode9和Swift4新特性。

XCode9新特性

新特性每次都是:更快、更高、更強

1. 支持遠程調試

從來沒有接過的iOS設備要先插入一次,然後在設備窗口選中 Connect via Network選項,之後就可以斷開設備進行網絡調試。

如果是已經插入過的手機,插入Mac後選中Xcode的 Window -> Devices and Simulators -> Devices -> 勾選Connect via network

這裡有一個前提:iPhone必須升級到iOS11,電腦和iPhone在同一個區域網下。

勾選過一次,以後調試就不用數據線了,爽不爽!手機右邊有個網絡小星球說明是遠程設備。

2. Xcode綁定Github帳號

點擊右上角Xcode -> Preferences ->

3. 支持Swift類重命名

原來的版本一直不支持Swift語言的重命名操作,終於啊終於此時應該高歌一曲:

等了好久終於等到今天夢了好久終於 把夢實現前途漫漫任我闖幸虧還有你在身旁盼了好久終於 盼到今天夢了好久終於 把夢實現.

4. Swift低版本兼容

原來每次升級Xcode都要convert Swift進行升級,現在Xcode9兼容Swift3.2

5. Main Thread Checker

Xcode9以前不會自動檢測是否在非主線程更新UI,這樣會有安全隱患。現在Xcode9自動附帶了Main Thread Checker功能。一旦在非主線程操作UI就會在命令行警告:類似如下:

 
Main Thread Checker: UI API called on a background thread: -[UIView subviews]

PID: 28353, TID: 267810, Thread name: (none), Queue name: com.apple.root.user-initiated-qos, QoS: 25

現在讀秒項目中第三方的小米推送和Bugtags、諸葛IO都有這個問題,需要更新到最新版。小米推送一直沒更新,我上周給他們發郵件反饋周四才更新。

6. 模擬器支持多開

可以同時打開多個型號模擬器

7. 標示功能

範圍標示

將遊標移到 { } 、( ) 或是 class、func、if、for 等關鍵字時,按住 command 鍵,Xcode 將聰明地標示對應的 class、function、if、for 區塊。

提示功能

跟剛剛一樣,將遊標移到關鍵字上,按住 command 鍵,然後點擊,即可出現貼心的提示選單。

比方如圖所示,遊標停在 if 上,按住 command 鍵點擊後提示選單出現 Add 「else」 Statement 和 Add 「else if」 Statement,Extract Method 等選項。選擇 add 「else」 Statement 後,自動完成 else { } 的輸入。

8. 協議自動補全

Swift的protocol中必須實現的函數當沒有實現時會報錯,有時我們需要點擊協議定義的地方查看必須實現那些函數。現在Xcode9支持自動補全必須實現的函數

例如UIViewController遵循UITableViewDataSource協議,當未實現函數時會有紅色錯誤提示,點擊Fix就會自動補全。

9. 代碼段自動抽出函數

選中一段代碼,右鍵選擇Refactor -> Extract Method 就會把選中的代碼段單獨抽出一個函數。這個功能在代碼重構中很有用。

10. 自定義顏色名稱

可以在 Assets.xcasset 裡添加顏色,取個名稱,然後在代碼或者 Storyboard 中引用這個顏色了。

在 Assets.xcassets 頁面,右鍵選擇New Color Set

然後設置顏色和名字

在xib或者sb中使用的時候可以直接在Named Colors中選擇

代碼中使用,現在代碼中只能iOS11以上可以用

 
if #available(iOS 11.0, *) {

    self.view.backgroundColor = UIColor(named:"MainBlue")

}

11. Debug View Hierarchy可以顯示ViewController了

Debug View Hierarchy是一個很好的頁面調試工具,方便研究頁面上的控制項,原來是無法看到當前Controller的,現在Xcode9中可以看到了。

12.支持Markdown,可以在xcode中查閱、編輯markdown文件Swift4更新1. Extension可以訪問private的屬性

在Swift3中類、結構體和枚舉的擴展中不能訪問private屬性。

下面這種寫法會報錯:'strName' is inaccessible due to 'private' protection level

 
class ViewController: UIViewController {

    private var strName:String = "test"

}

extension ViewController{

    func testFunc()  {

        print("\(self.strName)") 

    }

}

必須把private換成fileprivate才可以,但是權限又被擴大了。到了Swift4中extension也可以訪問private中的屬性了。

2. 類型和協議的組合類型
 

class Person {

     var name:String?

}

class Student: Person {

    var sId:Int = 0

}

class Teacher: Person {

}

protocol Runnable {

    func run()

}

protocol Singing {

    func sing()

}

extension Student :Runnable, Singing{

    func run() {

        print("\(self.name ?? "")會跑步")

    }

    func sing() {

         print("\(self.name ?? "")會唱歌")

    }

}

extension Teacher :Runnable{

    func run() {

        print("\(self.name ?? "")會跑步")

    }

}

extension ViewController {

    

    func test2(human:Person&Singing&Runnable)  {

        if (human.name?.count ?? 0) > 0 {

            human.run()

            human.sing()

        }

    }

}

如果在Swift3中只能像下面這樣寫

 
func test2(man:Person)  {

    if (man.name?.characters.count ?? 0) > 0 {

        if let mm = man as? Runnable{

            mm.run()

        }

        if let mm = man as? Singing{

            mm.sing()

        }

    }

}

3. 新的Key Paths 語法

Swift4可以使用\+點語法的形式創建KeyPath

let path:KeyPath = \Apple.color

例子:

 
//MARK: 3.0 新的Key Path語法

class Apple {

    var color:UIColor

    init(color:UIColor) {

        self.color = color

    }

}

extension ViewController {

    func test3(){

        let apple = Apple(color: UIColor.red)

        let c = apple[keyPath:\Apple.color]

        print("\(c)")

    }

}

Swift4的KeyPath具有以下優勢:

4. 下標支持泛型

在Swift4之前,下標屬性只能返回Any類型,現在可以添加泛型約束

 
struct School<Key:Hashable , Value> {

    var studens:[Key: Value]

    init(studens:[Key: Value]) {

        self.studens = studens

    }

    subscript<Value>(key: Key) -> Value? {

        return studens[key] as? Value

    }

}

extension ViewController {

    func test4(){

        let tfboys = School(studens: ["001":"王俊凱","002":"易烊千璽","003":"王源"])

        let name:String? = tfboys["001"]

        print("\(name ?? "")") 

    }

}

5. 字符串5.1 可以直接獲取字符串長度了

Swift3中想要獲取字符串的長度必須: str.characters.count ,現在可以str.count直接獲得了。

Swift 3 中的 String 需要通過 characters 去調用的一些屬性方法,在 Swift 4 中可以通過 String 對象本身直接調用。

5.2 字符串獲取子串語法糖… One-sided Slicing

Swift3中獲取子串

 

let values = "歡迎關注微信公眾號:樂Coding"

let startIndex = values.index(values.startIndex, offsetBy: 3)

let subvalues = values[startIndex..<values.endIndex]

Swift4中可以使用...語法

 

extension ViewController{

    func test5() {

        let str = "歡迎關注微信公眾號:樂Coding"

        let start = str.index(str.startIndex, offsetBy: 2)

        let subStr = str[start...]

        let subStr2 = str[...start]

        print("\(subStr)  : \(subStr2)") 

    }

}

5.3  String增加了Collection的一些特性

在Swift4中字符串做了一些Collection類似功能函數的擴展(並不是實現Collection協議,而是使用起來更像Collection,更友好)。

 
func test6()  {

      

      let str = "Backwards"

      let str2 = str.reversed() 

      let reversedWord = String(str2)

      print(reversedWord) 

      

      for char in str {

          print(char, terminator: "") 

      }

      

      print("\n Map ---")

      _ = str.map {

          print($0.description+"...")

      }

      

      

      print("\n Filter ---")

      let filtered = str.filter {

          $0 == "c"

      }

      print("\(filtered)") 

      

      let letters = "abracadabra"

      let letterCount = letters.reduce(into: [:]) { counts, letter in

            counts[letter, default: 0] += 1

       }

      print("\(letterCount)") 

  }

5.4 多行字符串

swift3中寫多行字符串只能在字符串中添加\n,易讀性不好。Swift4中新增加了多行字符串語法""",注意"""要單獨佔一行。

 
func test7(){

    let mutableLineStr =

    """

    小明:

        你媽叫你回家吃飯。

                    小紅。

    """

    print(mutableLineStr)

}

列印結果:

6. 序列化的簡化

原來對象序列化,需要對象遵守NSCoding協議並實現下面三個方法,比較麻煩。

 
- (id)initWithCoder:(NSCoder *)coder;

- (void)encodeWithCoder:(NSCoder *)coder;

- (id)copyWithZone:(NSZone *)zone;

Swift4中只需要對象實現Codable協議。然後選擇把對象轉成Json(JSONEncoder)還是Plist(PropertyListEncoder)存儲。

 
struct Animal:Codable {

    var name: String

    var age: Int

}

extension ViewController {

    func test8(){

        let cat = Animal(name: "wildcat", age: 2)

        

        if let encoded = try? JSONEncoder().encode(cat) {

            UserDefaults.standard.set(encoded, forKey: "MyCat")

            UserDefaults.standard.synchronize()

        }

        

        let decode = UserDefaults.standard.object(forKey: "MyCat") as? Data

        if let cat2 = try? JSONDecoder().decode(Animal.self, from: decode!){

            print("\(cat.name)") 

        }

    }

}

7.  Dictionary and Set增強7.1 通過Sequence初始化

字典通過Sequence創建的函數聲明:

 
public init<S>(grouping values: S, by keyForValue: (S.Element) throws -> Key) rethrows where Value == [S.Element], S : Sequence

下面以數組轉字典為例,字典的key是元素在數組中下標

 
let students = ["Kofi", "Abena", "Efua", "Kweku", "Akosua"]

let dic  = Dictionary(grouping: students) { (element) -> Int in

    return students.index(of: element) ?? 0

}

print("dic: \(dic)")

7.2 字典過濾後類型不變

在Swift3中Dictionary調用filter後會返回一個數組,但我們肯定希望還是返回一個過濾後的Dictionary,在Swift4中按照我們希望的做了修改。

 
let cities = ["Shanghai": 24_256_800, "Karachi": 23_500_000, "Beijing": 21_516_000, "Seoul": 9_995_000];

let massiveCities = cities.filter { $0.value > 10_000_000 }

print("massiveCities: \(massiveCities)")

7.3 新增mapValues函數

先看下面例子:

 
let populations = cities.map { $0.value * 2 }

print("\(populations)")

我們原本希望populations返回的還是一個字典,只是值變成2倍,可是map在Swift4中並沒有這麼改,而是添加了一個mapValues()函數

 
let roundedCities = cities.mapValues { "\($0 / 1_000_000) million people" }

print("\(roundedCities)")

7.4 字典支持默認值

下面的let name =person["name", default: "Anonymous"]默認值語法,類似於let name = person["name"] ?? "Anonymous"

 
let person = ["name": "Taylor", "city": "Nashville"]

let name = person["name", default: "Anonymous"] 

print("\(name)") 

let create = person["create", default: "1984-01-01"]

print("\(create)") 

還可以看一個統計數組中元素出現次數的例子:

 
let favoriteTVShows = ["Red Dwarf", "Blackadder", "Fawlty Towers", "Red Dwarf"]

var favoriteCounts = [String: Int]()

for show in favoriteTVShows {

    favoriteCounts[show, default: 0] += 1

}

print("favoriteCounts: \(favoriteCounts)")

8. MutableCollection新增swapAt(::) 用來交換兩個位置的值
 
func test10() {

  var array = ["王俊凱","易烊千璽","王源"]

  array.swapAt(0, 1)

  print("\(array)")

  

}

相關焦點

  • Swift 5 新特性一覽
    App 瘦身新特性Swift 應用程式不再包含用於 Swift 標準庫的動態連結庫和用於運行 iOS 12.2,watchOS 5.2 和 tvOS 12.2 的設備的構建變體中的 Swift SDK overlays。因此,當為 TestFlight 進行測試部署時,或者在為本地開發分發瘦身應用的 archive 包時,Swift 應用程式可以更小。
  • 回顧Swift 3,展望Swift 4
    基於上述觀點,Lattner闡明了Swift 4所將具有的兩個首要設計目標,即「自3.0版本起,交付具有源碼穩定性承諾的版本,以及為標準庫提供ABI穩定性」。鑑於此,可預見核心團隊直到2017年春都將忙碌於第一階段。該階段的工作主要是針對影響現有ABI或者是導致現有標準庫特性發生重要改變的特性。
  • Swift和Objective-C中的屬性特性
    和copy特性不同的是,這個特性將會導致屬性的getter方法是用copyWithZone方法所返回的值,而不是返回屬性本身的值。因此,這個屬性的類型必須要遵循NSCopying協議。所有者特性對於ARC來說,上一節中所說的getter語意特性將被所有者特性所代替。在Objective-C中,擁有兩個所有者特性:strong和weak。
  • Swift 3 新特性
    Swift 3 的改動歸結下來主要有兩點:移除了在 Swift 2.2 就已經棄用的特性語言現代化問題讓我們從移除特性講起,畢竟這點能容易理解,而且在 Xcode 7.3 的時候我們遇到了相關警告。正如你所看到的,通過將 a 和 b 標記為變量,才能在函數體裡對兩個數進行修改。Swift 3 不在允許開發者這樣來將參數標記為變量了,因為開發者可能會在 var 和 inout 糾結不已。所以最新的 Swift 版本中,就乾脆移除了函數參數標記 var 的特性。如此,想要用 Swift 3 來寫上面的 gcd 函數,就要另闢蹊徑了。
  • iOS和macOS應用是Swift語言編寫的!
    某種意義上Swift作為蘋果的新商業戰略,將吸引更多的開發者入門,從而增強App Store和Mac Store本來就已經實力雄厚的應用數量基礎。Swift是蘋果2014年推出的全新的程式語言,它繼承了C語言、ObjC的特性,且克服了C語言的兼容性問題。
  • Swift 周報 第五期
    為了支持該特性, SE-0303 引入了最小初始 API,插件能夠通過該接口獲取那些被喚起構建的 Target 的相關信息。該提案擴展了插件 API 以提供更多上下文,包括更豐富的包圖表示。這是為將來支持新類型的插件做準備。
  • 讓不懂編程的人愛上iPhone開發(2017iOS11+Swift4+Xcode9版)-第5篇
    preferredStyle: .alert)let action = UIAlertAction(title:"ok",style: .default,handler: nil)alert.addAction(action)present(alert, animated: true, completion: nil)}在以上代碼中,黃色高亮部分是新添加或修改的部分
  • Swift 項目主管和大家聊了聊 Swift 5,ABI 穩定性最受關注
    蘋果在 2014 年發布了全新程式語言 Swift,到目前為止已經發展到了 Swift 4.0 版本,而 Swift 5 也即將在 WWDC 2019
  • OpenStack Swift存儲策略
    Swift可在比較便宜的通用硬體上構築具有極強可擴展性和數據持久性的存儲系統,支持多租戶,通過RESTfulAPI提供對容器(Container)和對象的CRUD操作。OpenStackSwift對象存儲及其存儲策略簡介Swift2.0於2014年7月8日發布,其中最重要的新特性是存儲策略(StoragePolicy),該特性改變了以往存儲系統中存儲策略由設計與實施方決定的做法,讓用戶能夠以Container為粒度,為不同需求的數據指定不同的副本數量、不同參數的糾刪碼、不同性能的存儲介質、不同地理位置、
  • 這5本免費Swift書籍,你早該讀了
    本書可在知識共享署名4.0國際(CC BY 4.0)許可下獲得。這本書介紹了Swift的現代語言特性,包括類型安全、泛型、類型推斷、閉包、自動內存管理和Unicode支持等。提供免費在線閱讀,如需PDF版本則要付費購買閱讀地址:https://www.aidanf.net/learn-swift/4、《What’s New in Swift 3》
  • 蘋果開源了Swift版Netty:SwiftNIO
    ChannelHandler 是高度可重用的組件,所以儘可能設計得輕量級,每個 ChannelHandler 只處理一種數據轉換,這樣就可以靈活組合各種 ChannelHandler,提升代碼的可重用性和封裝性。我們可以通過 ChannelHandlerContext 來跟蹤 ChannelHandler 在 ChannelPipeline 中的位置。
  • Swift 五年,ABI 終於穩定了!
    如今 Swift 可以更好地為當前和未來版本的蘋果作業系統 macOS、iOS、tvOS 和 watchOS 服務。與此同時,Swift 5 還引入了構建塊的新功能,包括重新實現 String、在運行時對執行內存的獨佔訪問和新數據類型,以及對動態可調用類型的支持。接下來,我們將一一探討 Swift 5 中的變化。
  • Swift 4.0 中對 Dictionary 的一系列改進
    value 無縫轉換另外一個比較有用的特性是,Dictionary 提供的 mapValues 方法。我們例子中的閉包返回的就是每個 key 對應的 Person 集合的數量,最生成了一個新的 Dictionary,裡面的 key 和之前一樣,只是對應的值變成了我們閉包中自定義的了。mapValues 方法同樣是一個幫助我們解決繁雜操作的工具方法。
  • OpenStack—Swift
    最適合存儲的數據類型的例子是虛擬機鏡像、圖片存儲、郵件存儲和存檔備份。Swift無需採用RAID(磁碟冗餘陣列),也沒有中心單元或主控結點。Swift通過在軟體層面引入一致性哈希技術和數據冗餘性,犧牲一定程度的數據一致性來達到高可用性(High Availability,簡稱HA)和可伸縮性,支持多租戶模式、容器和對象讀寫操作,適合解決網際網路的應用場景下非結構化數據存儲問題。
  • CocoaPods 1.9 新特性
    CocoaPods 1.9 增加了對 XCFrameworks 的支持,服務於 Pod 發布者的基於配置的依賴關係,所生成方案的代碼覆蓋率,以及其他增強功能和錯誤修復
  • Swift,你不得不學的5個原因
    然而,Swift集成了許多我喜歡的其他語言特性,如:protocols,closures,generics和tuples。  我不知道你是否已經開始探索Swift的魅力,這篇文章是我使用Swift一年半以來的一些觀察和感悟。 1、這不僅僅是為了iOS  當然,Swift在蘋果平臺上非常好用。
  • 國內銀行國際Swift Code(Swift代碼)查詢大全
    (2012年8月平安銀行與深圳發展銀行合併,兩行名稱統一為「平安銀行」,swift code代碼沿用原深圳發展銀行的「SZDBCNBS」,原平安銀行的swift code代碼「SZCBCNBS」撤銷使用)  廣發銀行swift code代碼:GDBKCN22  渤海銀行swift code代碼:CHBHCNBT  恆豐銀行swift code代碼:HFBACNSD
  • Swift 中的類與結構體
    類有繼承特性;結構體沒有。類實例可以被多次引用,有引用計數。類有反初始化器(析構函數)來釋放資源。類型轉換允許你在運行檢查和解釋一個類實例的類型。 main.swift -dump-parse   // 2 語義分析組件: 對AST進行類型檢查,並對其進行類型信息注釋swiftc main.swift -dump-ast   // 3 SILGen組件: 生成中間體語言,未優化的 raw SIL (生SIL)// 一系列在 生 SIL上運行的,用於確定優化和診斷合格,對不合格的代碼嵌入特定的語言診斷
  • SwiftSyntax
    這可以幫助此類工具實現一些編輯器相關的特性,例如代碼補全或者文件之間的跳轉。雖然 SwiftSyntax 不能像 SourceKit 一樣實現跳轉或者補全的功能,但在語法層面上也有很多應用場景,例如代碼格式化和語法高亮。揭秘 AST抽象語法樹在抽象層面上比較難以理解。因此我們先生成一個示例來一睹其貌。
  • Swift 編譯器中間碼 SIL
    缺點:Swift作為一種高級語言,有些高級特性,比如基於protocol的泛型。而且也是一門安全的語言,確保變量在使用之前被初始化、檢測不可執行的代碼(unreachable code)。於是為Swift編譯器增加了一層SIL來做這些事情。