Reference Type (class) _VS_ Value Type (enum, struct)

Mình dạy học thấy nhiều bạn còn lơ mơ về Reference Type và Value type quá nên viết lại cho mọi người rõ

Value type khác Reference type

Đặc điểm Value Type (Struct , enum) Reference Type (class)
Kế thừa Không kế thừa được. Nhưng hoàn toàn có thể conform with protocol Còn với enum, đây ko phải là kế thừa, đây chỉ là chỉ định ra tập giá trị liên quan này nó thuộc loại gì thôi có kế thừa được
khi gán dữ liệu var a = b tạo ra 1 bản copy mới của b sau đó gán cho a mọi thay đổi trên a đều ko liên quan đến b. Giống như việc mình cho bạn mình mượn quyển sách, bạn đó photo sách đó và dùng. Bạn viết gì lên trang sách đó ko liên quan đến quyển sách của mình. Bản chất việc gán chỉ là việc truyền địa chỉ (pointer) cuả object từ b cho a. (b chứa địa chỉ của object (pointer) và gán địa chỉ đó cho a) Khi đó cả a và b cùng trỏ đến 1 vùng nhớ chung. Việc này giống như việc mình cho bạn biết chỗ cất sách, mình và bạn cùng dùng chung quyển sách đó, khi bạn viết lên trang sách thì quyển sách đó cũng ảnh hưởng đến mình.
Khi bạn khai báo let car = Car() Bởi bản chất của struct ko sửa, chỉ tạo mới. Mọi sự thay đổi thuộc tính của struct, struct sẽ tạo một object mới gán lại object cũ tại cùng 1 địa chỉ ô nhớ, vì vậy việc khai báo let ko được chấp nhận Việc khai báo let với class chỉ đảm bảo là địa chỉ của pointer ko thay đổi, nghĩa là các object đấy ko được thay đổi thành object khác, nhưng các properties trong đó vẫn có thể thay đổi được
Khi bạn thêm 1 method Cũng vì bản chất của struct là ko sửa, chỉ tạo mới vì vậy method không thể trực tiếp thao tác với properties, thay vào đó method phải khai bác là mutable để có thể tạo ra một object khác với property mới thay vào vị trí cũ Class thì chúng ta có thể sử dụng Method để thay đổi các giá trị của properties bình thường
Khi truyền như một tham số cho function Do parameter của function luôn là constant vì vậy, chúng ta không thể thay đổi thuộc tính cho object car trong trường hợp này Trong trường hợp này, dù parameter của function là constant chúng ta vẫn có thể thay đổi thuộc tính trong object Car, miễn là ko thay đổi object được truyền vào
Trong thực tế Do việc sử dụng struct hoàn toàn là copy nên khi ta gia công dữ liệu nó sẽ không ảnh hưởng đến dữ liệu cũ, chính vì vậy nó có ưu điểm là sẽ tránh được sai sót trong quá trình xử lý dữ liệu, chỉ khi nào dữ liệu thực sự chuẩn, ta mới chủ động gán lại giá trị cho giá trị ban đầu Việc sử dụng class thì việc sửa chữa dữ liệu dễ dàng hơn, bỏ qua được thao tác gán lại dữ liệu bởi bản chất chúng ta đang thao tác trên cùng 1 object. Nhưng nó có nhược điểm là dễ bị sai sót bởi tất cả các thao tác xử lý đều được thực hiện trên cùng 1 object.
Các loại dữ liệu hay gặp String, Int, Double, CGPoint, CGSize, CGFloat, Array, Dictionary , đều là Value Type UIView, UIViewController, UITableView,... là các Reference Type. Lưu ý: NSString, NSNumber, NSArray, and NSDictionary cũng là các reference Type

Khi nào chúng ta chọn sử dụng Struct hoặc Class ?

Chúng ta có thể sử dụng struct trong một trong những điều kiện dưới đây:

  • Để đóng gói những giá trị khá đơn giản
  • Bạn mong đợi giá trị đóng gói được sao chép hơn là tham chiếu đến khi bạn gán hoặc truyền quanh các instance của struct đó.
  • Tất cả các stored property của struct đều phải là value Type, và cũng mong muốn copy thay cho tham chiếu
  • Cấu trúc không cần kế thừa từ một loại nào khác.

Ví dụ một số suggest khi dùng Struct

    struct ShapeSize {
        var height: Double
        var weight: Double
    }
    
    struct Range {
        var startPoint: Int
        var length: Int
    }
    
    struct 3DCoordinateSystem {
        var x: Double
        var y: Double
        var z: Double
     }

Chúng ta sử dụng Class trong hầu hết các trường hợp khác.