12/08/2018, 13:03

Một số thay đổi trong swift 2

Swift 2 bao gồm một số tính năng mới như cải tiến việc quản lý lỗi, protocol extensions, và kiểm tra phiên bản. Quản lý lỗi Khi một function bị lỗi, cách tốt nhất là bắt được lỗi đó và hiểu được tại sao nó lại lỗi. Swift phiên bản 1 thiếu hụt một mô hình quản lý lỗi thích hợp. Trong Swift 2, ...

Swift 2 bao gồm một số tính năng mới như cải tiến việc quản lý lỗi, protocol extensions, và kiểm tra phiên bản.

Quản lý lỗi

Khi một function bị lỗi, cách tốt nhất là bắt được lỗi đó và hiểu được tại sao nó lại lỗi. Swift phiên bản 1 thiếu hụt một mô hình quản lý lỗi thích hợp. Trong Swift 2, nó đi kèm một mô hình quản lý lỗi ngoại lệ bằng cách sử dụng các từ khóa try/ throw / catch.

tưởng tượng bạn đang mô hình hóa một động cơ xe hơi. Động cơ này có thể bị lỗi vì những lý do sau đây

No fuel
Oil leakage
Low battery

trong Swift, các lỗi được đại diện bởi các giá trị của các kiểu phù hợp với protocol ErrorType. Trong trường hợp này, bạn có thể tạo ra một enumeration chấp nhận ErrorType để mô hình hóa các điều kiện lỗi.

enum CarEngineErrors: ErrorType {
    case NoFuel
    case OilLeak
    case LowBattery
}

tạo ra một function có khả năng ném ra một lỗi, bạn sử dụng từ khóa throws trong khai báo của nó. Dưới đây là một ví dụ:

func checkEngine() throws {
}

Để throw ra một lỗi trong function này, bạn sử dụng câu lệnh throw . Dưới đây là một function mẫu thực hiện một kiểm tra đơn giản về động cơ xe hơi nói trên:

let fuelReserve = 20.0 let oilOk = true let batteryReserve = 0.0

func checkEngine() throws {
    guard fuelReserve > 0.0 else {
        throw CarEngineErrors.NoFuel
    }

    guard oilOk else {
        throw CarEngineErrors.OilLeak
    }

    guard batteryReserve > 0.0 else {
        throw CarEngineErrors.LowBattery
    }
}

Từ khóa guard có thể là mới đối với bạn. Nó được giới thiệu lần đầu tiên trong Swift 2 nhằm cải tiến luồng control. Khi đoạn code trên thực thi đến câu lệnh guard, đầu tiên nó sẽ kiểm tra điều kiện. Nếu ước lượng điều kiện trả về false, thì phần else sẽ được thực thi. Trong đoạn code ở trên, function đó sẽ ném ra một lỗi nếu một điều kiện nào đó không thỏa mãn.

func startEngine() {
    try checkEngine()
}

Nếu viết đoạn code trên trong Playgrounds, bạn sẽ kết thúc với một lỗi vì chúng ta vẫn chưa quản lý những lỗi đó. Mô hình quản lý lỗi trong Swift yêu cầu bạn phải sử dụng một câu lệnh do-catch để bắt tất cả các lỗi và xử lý chúng.

Dưới đây là một function mẫu xác định phải làm gì khi bắt được một lỗi:

func startEngine() {
    do {
        try checkEngine()
        print("Engine started", appendNewline: true)
    } catch CarEngineErrors.NoFuel {
        print("No Fuel!")
    } catch CarEngineErrors.OilLeak {
        print("Oil Leak!")
    } catch CarEngineErrors.LowBattery {
        print("Low Battery!")
    } catch {
        // Default
        print("Unknown reason!")
    }
}

Mỗi mệnh đề catch phù hợp với một lỗi cụ thể và bạn xác định sẽ làm gì trong phần body. Trong ví dụ phía trên, biến batteryReserve được thiết lập giá trị bằng 0. Trong trường hợp này, lỗi .LowBattery sẽ được thow ra khi bạn gọi function startEngine().

thiết lập giá trị của biến batteryReserve thành 1.0. Trong trường hợp này, không có lỗi nào bị ném ra và dòng chữ 'Engine started’ được in ra.

Tương tự như câu lệnh switch, mô hình quản lý lỗi trong Swift 2 là rất toàn diện. Bạn phải quản lý tất cả các lỗi có thể xảy ra. Đây là lý do tại sao chúng ta cần phải bao gồm một mệnh đề catch mà không xác định một pattern.

Loại bỏ phương thức println()

Trong Swift 2, chúng ta chỉ có thể sử dụng print() để viết một cái gì đó ra ngoài. Apple đã kết hợp cả hai function println()print() thành một. Nếu bạn muốn xuất ra một cái gì đó cùng một dòng mới, bạn có thể thiết lập tham số appendNewline bằng true

print("Engine started", appendNewline: true)

Protocol Extensions

Ở phiên bản đầu tiên của Swift, bạn có thể sử dụng các extension để bổ sung thêm các chức năng mới tới một class, structure hoặc enumeration đang tồn tại. Swift 2 cho phép các lập trình viên áp dụng các extension tới các kiểu protocol. Với Protocol Extensions, bạn có thể bổ sung thêm các function hoặc properties tới tất cả các class tuân theo một protocol nhất định. Điều này là rất hữu ích khi bạn muốn mở rộng các chức năng của protocol

tạo ra một protocol mới có tên là Awesome. Protocol này có thể được implemented bởi bất kỳ kiểu nào mà cung cấp một cách để trả về một chỉ số của một đối tượng cụ thể theo tỷ lệ phần trăm.

protocol Awesome {
    func awesomenessPercentage() -> Float
}

khai báo hai class mà thông qua protocol mới đó. Mỗi class thực hiện phương thức được yêu cầu của protocol Awesome đó

class Dog: Awesome {
    var age: Int!
    func awesomenessPercentage() -> Float {
        return 0.85
    }
}

class Cat: Awesome {
    var age: Int!
    func awesomenessPercentage() -> Float {
        return 0.45
    }
}

let dog = Dog()
dog.awesomenessPercentage()

let cat = Cat()
cat.awesomenessPercentage()

bạn muốn mở rộng protocol Awesome để cung cấp một thuộc tính awesomenessIndex, trong đó sử dụng kết quả của phương thức awesomenessPercentage() để tính toán chỉ số tương ứng. Bạn có thể viết như sau

extension Awesome {
    var awesomenessIndex: Int {
        get {
            return Int(awesomenessPercentage() * 100)
        }
    }
}

Kiểm tra phiên bản sẵn có

Trước khi có Swift 2, không có cách chuẩn nào để làm công việc kiểm tra phiên bản đó. Ví dụ, class NSURLQueryItem chỉ có từ phiên bản iOS 8 trở đi. Nếu bạn sử dụng class này trên những phiên bản iOS cũ hơn, bạn sẽ kết thúc với một lỗi và có thể đó là nguyên nhân gây cho ứng dụng của bạn bị crash. Để ngăn chặn lỗi này, bạn có thể thực hiện việc kiểm tra phiên bản như sau:

if NSClassFromString("NSURLQueryItem") != nil {
    // iOS 8 or up
} else{
    // Earlier iOS versions
}

một cách để kiểm tra xem liệu class đó có tồn tại hay không. Bắt đầu với Swift 2, cuối cùng nó cũng đi kèm một hỗ trợ built-in trong việc kiểm tra tính sẵn sàng của các API. Bạn có thể dễ dàng xác định một điều kiện có sẵn sàng hay không để khối code sẽ chỉ thực thi trong các phiên bản iOS xác định.

if #available(iOS 8, *) {
    // iOS 8 or up
    let queryItem = NSURLQueryItem()

} else {
    // Earlier iOS versions

}

do-while thay thế thành repeat-while

Vòng lặp do-while cổ điển giờ đây được đổi tên thành repeat-while

var i = 0
repeat {
    i++
    print(i)
} while i < 10
0