帶你初識Swift4.0,踏入Swift的大門

imango 6年前發布 | 24K 次閱讀 Swift Apple Swift開發

背景

由于Swift4之前的版本也看過好幾遍,不過好久沒看有點忘記了,不過這次看也是非常得心應手。項目中也準備引入Swift,所以作者再次詳細看了 The Swift Programming Language (Swift 4.0.3) 英文官方文檔一遍,并且詳細列舉了本人認為大家比較常用并且應該掌握的所有知識點。這里不做深入探究,如果哪里不懂的話,可以自行深入研究。

所有知識點

  • 數組可以用“+”表示兩個數組組合

  • 字符串截取等操作很簡潔

let greeting = "Hello, world!" let index = greeting.index(of: ",") ?? greeting.endIndex let beginning = greeting[..
  • Dictionary可以遍歷,并且支持移除操作

airports["APL"] = nil 或 removeValue(forKey:)

遍歷:

for (airportCode, airportName) in airports {     print("(airportCode): (airportName)") }
  • switch語法很強大,很靈活,支持任何類型,比如字符串、范圍、管道等等。而且不用break語句

case "a", "A": case 1..<5: case (-2...2, -2...2) case let (x, y) where x == y
  • guard關鍵詞使用使語句更簡單明了

  • #available判斷api版本更簡潔

if #available(iOS 10, macOS 10.12, *) {     // Use iOS 10 APIs on iOS, and use macOS 10.12 APIs on macOS } else {     // Fall back to earlier iOS and macOS APIs }
  • 函數可以返回多個值

func minMax(array: [Int]) -> (min: Int, max: Int) {     var currentMin = array[0]     var currentMax = array[0]     for value in array[1.. currentMax {             currentMax = value         }     }     return (currentMin, currentMax) }
  • 函數參數可以設置默認值

func someFunction(parameterWithoutDefault: Int, parameterWithDefault: Int = 12) {     // If you omit the second argument when calling this function, then     // the value of parameterWithDefault is 12 inside the function body. } someFunction(parameterWithoutDefault: 3, parameterWithDefault: 6) // parameterWithDefault is 6 someFunction(parameterWithoutDefault: 4) // parameterWithDefault is 12
  • 可變參數...

func arithmeticMean(_ numbers: Double...) -> Double {     var total: Double = 0     for number in numbers {         total += number     }     return total / Double(numbers.count) } arithmeticMean(1, 2, 3, 4, 5)
  • inout 可以修改外部變量。與c語言指針有點類似

func swapTwoInts(_ a: inout Int, _ b: inout Int) {     let temporaryA = a     a = b     b = temporaryA
  • 函數可以與屬性變量一樣對待。可以傳遞、取值等

  • 閉包(Closures)與Block類似

{ (parameters) -> return type in     statements }

*@escaping和@autoclosure修飾閉包 @escaping使閉包在函數執行結束之前不會被執行。

var completionHandlers: [() -> Void] = [] func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {     completionHandlers.append(completionHandler)//閉包沒有執行,而是加到數組中了 }

@autoclosure簡化了閉包的代用,不過代碼會變的難懂,蘋果建議盡量不使用

// customersInLine is ["Alex", "Ewa", "Barry", "Daniella"] func serve(customer customerProvider: () -> String) {     print("Now serving (customerProvider())!") } serve(customer: { customersInLine.remove(at: 0) } ) // Prints "Now serving Alex!"

使用之后:

// customersInLine is ["Ewa", "Barry", "Daniella"] func serve(customer customerProvider: @autoclosure () -> String) {     print("Now serving (customerProvider())!") } serve(customer: customersInLine.remove(at: 0))//大括號沒有啦 // Prints "Now serving Ewa!"
  • 枚舉功能很強大,很靈活,可以枚舉的類型非常多,比如string、character、integer。

enum Barcode {     case upc(Int, Int, Int, Int)     case qrCode(String) } var productBarcode = Barcode.upc(8, 85909, 51226, 3) switch productBarcode { case .upc(let numberSystem, let manufacturer, let product, let check):     print("UPC: (numberSystem), (manufacturer), (product), (check).") case .qrCode(let productCode):     print("QR code: (productCode).") }
enum Planet: Int{} enum ASCIIControlCharacter: Character {} enum CompassPoint: String {}
  • indirect表示枚舉中使用了自己

enum ArithmeticExpression {     case number(Int)     indirect case addition(ArithmeticExpression, ArithmeticExpression)     indirect case multiplication(ArithmeticExpression, ArithmeticExpression) }

indirect enum ArithmeticExpression {     case number(Int)     case addition(ArithmeticExpression, ArithmeticExpression)     case multiplication(ArithmeticExpression, ArithmeticExpression) }
  • struct&&class struct傳遞是值傳遞;class是引用傳遞

In Swift, many basic data types such as String, Array, and Dictionary are implemented as structures. This means that data such as strings, arrays, and dictionaries are copied when they are assigned to a new constant or variable, or when they are passed to a function or method.
  • ===和!==用來比較對象

  • lazy懶加載,使用的時候再加載

  • 僅讀屬性。將get、set移除,直接返回,可以用來實例單例

struct Cuboid {     var width = 0.0, height = 0.0, depth = 0.0     var volume: Double {         return width * height * depth     } }
  • mutating用來修改struct和enum。因為二者是不能不能被自己的實例對象修改屬性變量

struct Point {     var x = 0.0, y = 0.0     mutating func moveBy(x deltaX: Double, y deltaY: Double) {         x += deltaX         y += deltaY     } } var somePoint = Point(x: 1.0, y: 1.0) somePoint.moveBy(x: 2.0, y: 3.0) print("The point is now at ((somePoint.x), (somePoint.y))") // Prints "The point is now at (3.0, 4.0)" **注意let不能修改** let fixedPoint = Point(x: 3.0, y: 3.0) fixedPoint.moveBy(x: 2.0, y: 3.0) // this will report an error
enum TriStateSwitch {     case off, low, high     mutating func next() {         switch self {         case .off:             self = .low         case .low:             self = .high         case .high:             self = .off         }     } } var ovenLight = TriStateSwitch.low ovenLight.next() // ovenLight is now equal to .high ovenLight.next() // ovenLight is now equal to .off
  • class和static都可修飾類方法,class修飾的可以被子類重寫

  • 腳標(Subscripts)。可以類、結構體、枚舉定義腳標從而快速訪問屬性等。

subscript(index: Int) -> Int {     get {         // return an appropriate subscript value here     }     set(newValue) {         // perform a suitable setting action here     } }
  • final可以防止被子類繼承。

  • deinit 只有類有,當類銷毀時會被回調。

  • ?是否為nil;??設置默認值

  • 異常處理

do {     try expression     statements } catch pattern 1 {     statements } catch pattern 2 where condition {     statements }

try!明確知道不會拋出異常。

  • defer代碼塊執行后必須執行的代碼

func processFile(filename: String) throws {     if exists(filename) {         let file = open(filename)         defer {             close(file)         }         while let line = try file.readline() {             // Work with the file.         }         // close(file) is called here, at the end of the scope.     } }
  • is判斷是否某個類型;as? 或 as!轉換至某個類型

  • Extensions與oc的category類似

extension SomeType: SomeProtocol, AnotherProtocol {     // implementation of protocol requirements goes here }
  • Protocols

protocol SomeProtocol {     // protocol definition goes here }

使用

struct SomeStructure: FirstProtocol, AnotherProtocol {     // structure definition goes here }
protocol SomeProtocol {     var mustBeSettable: Int { get set }//有get和set方法     var doesNotNeedToBeSettable: Int { get }//只有get方法,不能單獨設置,只能在初始化的時候設置。 }
  • 檢查是否遵循了某個協議

  • is遵循了返回true,否則返回false

  • as?遵循了正常轉換,否則為nil

  • as!遵循了正常轉換,否則拋出錯誤

  • 泛型(Generic);通常使用T、U、V等大寫字母表示。

func someFunction(someT: T, someU: U) {     // function body goes here }

  • weak或unowned(與oc的unsafe_unretained類似)解決循環應用的問題

weak var tenant: Person?

  • 訪問控制權限(open > public > interal > fileprivate > private)

  • private

    private 訪問級別所修飾的屬性或者方法只能在當前類里訪問。 (注意:Swift4 中,extension 里也可以訪問 private 的屬性。)

  • fileprivate

    fileprivate 訪問級別所修飾的屬性或者方法在當前的 Swift)

  • internal(默認訪問級別,internal修飾符可寫可不寫)

    internal 訪問級別所修飾的屬性或方法在源代碼所在的整個模塊都可以訪問。 如果是框架或者庫代碼,則在整個框架內部都可以訪問,框架由外部代碼所引用時,則不可以訪問。 如果是 App 代碼,也是在整個 App 代碼,也是在整個 App 內部可以訪問。

  • public

    可以被任何人訪問。但其他 module 中不可以被 override 和繼承,而在 module 內可以被 override 和繼承。

  • open

    可以被任何人使用,包括 override 和繼承。

 

 

來自:http://www.cocoachina.com/ios/20180129/21979.html

 

 本文由用戶 imango 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!