Bài 17: Properties trong swift - Lập trình Swift cơ bản

Đăng bởi: Admin | Lượt xem: 2416 | Chuyên mục: Swift


Properties trong Swift có chức năng liên kết các giá trị với một class, structure hay enumeration cụ thể. 
Properties có 2 loại là stored properties và computed properties. Nếu như 
stored properties có nhiệm vụ lưu trữ giá trị constant, variable và chỉ được cung cấp bởi class, structure thi computed  properties được cung cấp bởi class, structure và enums và đảm nhận nhiệm vụ tính toán.
Thông thường, stored hay computed properties sẽ liên kết với instance của một loại, một dạng (type) nào đó. Nhưng đôi khi,  properties cũng có thể tự liên kết với type, những properties như thế được gọi là type properties. 

Stored Properties

Như đã giải thích ở phần trên, stored property  là những variable hay constant được lưu trữ l. Stored properties có thể là variable stored properties (với từ khoá var) hoặc constant stored properties (với từ khoá let).
Bạn sẽ chắc chắn không thể thay đổi được những đặc tính của instance nếu như instance là  của một structure và gán instance đó cho một constant, ngay cả khi bạn khai báo chúng như là variable properties:
struct SuperMarket {

    var address: String

    let size: String

}

let vinMart = SuperMarket(address: "Danang", size: "small")

vinMart.address = "Dalat"

// Error in compiler
Ở ví dụ trên, chúng tôi đã khai báo vinMart như một constant nên giá trị của address sẽ không thể thay thế được, ngay cả khi address là variable property. 
Nguyên nhân là do structures là value types, một khi  instance của value type được khai báo là constant, thì tất cả các properties của nó cũng vậy. Tuy nhiên, nếu như  bạn gán một instance của reference type cho một constant, bạn hoàn toàn có thể thay đổi variable properties của instance đó.

Lazy Stored Properties

Một lazy stored property có thể hiểu là một property có giá trị ban đầu không được tính toán. Do giá trị khởi tạo không được phép truy cập khi quá trình tạo instance chưa hoàn thành nên lazy property luôn được coi là một variable (với từ khoá var).
Ngược lại, constant properties phải có giá trị trước khi quá trình khởi tạo hoàn thành nên nó không phải là một lazy.
Lazy properties sẽ có ích khi giá trị của property chưa được xác định mà  phụ thuộc vào các yếu tố bên ngoài cho đến lúc mà một instance hoàn thành và giá trị khởi tạo đòi hỏi phức tạp hay tính toán nhiều,..
class LoadImage {

    /*

     LoadImage is a class to load image from an external resource.

     The class is assumed to take a nontrivial amount of time to initialize.

     */

    var imageData = "data.txt"

}

class ImageManager {

    lazy var loader = LoadImage()

    var data = [String]()

}

let manager = ImageManager()

manager.data.append("Image data")
Ở ví dụ trên, property loader thực chất vẫn chưa được khởi tạo và nó chỉ được khởi tạo trong lần truy cập đầu tiên. 

Computed Properties

Một loại property chuyên cung cấp getter và optional setter để nhận, thiết lập các properties và giá trị một cách gián tiếp thay vì lưu trữ nó.
struct Point {

    var x = 0.0, y = 0.0

}

struct Size {

    var width = 0.0, height = 0.0

}

struct Rect {

    var origin = Point()

    var size = Size()

    var center: Point {

        get {

            let centerX = origin.x + (size.width / 2)

            let centerY = origin.y + (size.height / 2)

            return Point(x: centerX, y: centerY)

        }

        set(newCenter) {

            origin.x = newCenter.x - (size.width / 2)

            origin.y = newCenter.y - (size.height / 2)

        }

    }

}

var square = Rect(origin: Point(x: 0.0, y: 0.0),

                  size: Size(width: 10.0, height: 10.0))

let initialSquareCenter = square.center

square.center = Point(x: 15.0, y: 15.0)

print("square.origin is now at (\(square.origin.x), \(square.origin.y))")

// Prints "square.origin is now at (10.0, 10.0)"
Property center trong struct Rect là một computed property, nó khởi tạo giá trị của mình bằng cách nhận giá trị của origin và size, ngay sau khi được thiết lập giá trị mới, nó sẽ thay đổi giá trị của origin và size tương ứng.

Property Observers

Đúng như tên gọi của nó property observers có nhiệm vụ quan sát và phản ánh lại những sự thay đổi giá trị của property. 
Bạn hoàn toàn có thể thêm property observers vào bất cứ stored properties nào,  trừ lazy. Thậm chí, bạn có thể thêm nó vào bất kỳ properties kế thừa nào được overriding trong subclass. 
Observer cho một properties sẽ được định nghĩa theo những cách sau:
  • Sử dụng willSet, được gọi trước khi giá trị được lưu trữ
  • Sử dụng didSet, được gọi ngay khi một giá trị mới được lưu trữ
class StepCounter {

    var totalSteps: Int = 0 {

        willSet(newTotalSteps) {

            print("About to set totalSteps to \(newTotalSteps)")

        }

        didSet {

            if totalSteps > oldValue  {

                print("Added \(totalSteps - oldValue) steps")

            }

        }

    }

}

let stepCounter = StepCounter()

stepCounter.totalSteps = 200

// About to set totalSteps to 200

// Added 200 steps

stepCounter.totalSteps = 360

// About to set totalSteps to 360

// Added 160 steps

stepCounter.totalSteps = 896

// About to set totalSteps to 896

// Added 536 steps

Type Properties

Type properties là những properties chỉ có một bản sao duy nhất dù có thêm bao nhiêu instances được tạo ra đi chăng nữa.
Khai báo stored và computed type properties với từ khoá static.
struct SomeStructure {

    static var storedTypeProperty = "Some value."

    static var computedTypeProperty: Int {

        return 1

    }

}

enum SomeEnumeration {

    static var storedTypeProperty = "Some value."

    static var computedTypeProperty: Int {

        return 6

    }

}

class SomeClass {

    static var storedTypeProperty = "Some value."

    static var computedTypeProperty: Int {

        return 27

    }

    class var overrideableComputedTypeProperty: Int {

        return 107

    }

}
//Cũng giống như instance properties, type properties được gọi bằng dấu chấm. Tuy nhiên, type properties được truy vấn bởi type, không phải instance của type đó. 
//Xem ví dụ dưới đây để hiểu thêm nhé

print(Some Structure.storedTypeProperty)

// Prints "Some value."

SomeStructure.storedTypeProperty = "Another value."

print(SomeStructure.storedTypeProperty)

// Prints "Another value."

print(SomeEnumeration.computedTypeProperty)

// Prints "6"

print(SomeClass.computedTypeProperty)

// Prints "27"
Hy vọng ra qua bài viết trên sẽ giúp bạn hiểu và áp dụng  các loại properties trong Swift một cách thành thạo và hiệu quả nhất. 
Bài tiếp theo: Methods trong swift >>
vncoder logo

Theo dõi VnCoder trên Facebook, để cập nhật những bài viết, tin tức và khoá học mới nhất!