Bạn đang nâng cấp dự án của mình lên Swift 5 chưa? Đó là một trải nghiệm không đau đớn và mệt mỏi như xưa nữa, bởi vì code của Swift 5 thay đổi khá ít, chỉ thêm các tính năng mới. Đặc biệt, bạn có thể bật cảnh báo cho enum bằng cách thêm giá trị không xác định(unknown values) và @Frozen là gì?. Bây giờ, chúng ta sẽ tìm hiểu nó trong bài sau đây.

Các thêm giá trị không xác định để bật cảnh báo cho enum

Vấn đề là gì? Ở đây, một đoạn mã mà tôi có thể sử dụng để điều chỉnh bố cục cho các kích thước khác nhau của layer. Nó bao gồm tất cả các case có thể có của UIUserInterfaceSizeClass.

Với Phiên bản ngôn ngữ Swift 5 trong dự án của tôi, Xcode thưởng cho tôi một cảnh báo như sau:

Đẩy đủ cảnh báo là:

Switch covers known cases, but UIUserInterfaceSizeClass may have additional unknown values, possibly added in future versions

Handle unknown values using “@unknown default”

Nếu bạn chấp nhận sửa lỗi, Xcode sẽ thêm một mặc định @unknown default:

Bạn có thể cho nó chạy fatalError() khi gặp case trên, nhưng nó có nghĩa là gì?

Frozen and non-frozen trong enums

Biểu thức Switch trong Swift phải đầy đủ các case hoặc bao gồm trường hợp default.

Điều gì xảy ra nếu Apple giới thiệu một số enum UIUserInterfaceSizeClass mới bao gồm .tiny hoặc .larsh trong iOS 13? Khi bạn xây dựng với SDK mới này thì trình biên dịch sẽ phàn nàn rằng Switch này đang thiếu vài case nào đó. Một cách để đáp ứng trình biên dịch là bao gồm một case mặc định(default). Tôi có thể viết lại Switch của mình như sau:

Việc dùng switch kiểu này sẽ không nắm và xử lý từng case được nhưng nó xử lý tất cả các trường hợp chưa biết và trong tương lai. Điều đó tốt, nhưng nó có lợi cho trình biên dịch, và cho thư viện nhị phân khi nó biết rõ các case trong lúc biên dịch. Bạn cũng có thể cảnh báo khi enum có một sự nâng cấp mới nào đó.

Đề xuất tiến hóa Swift SE-0192 thêm cú pháp @unknown default: cho phép bạn tiếp tục sử dụng switch với tất cả các trường hợp và cho mọi trường hợp mới trong tương lai:

case @unknown default: Nó có thể được sử dụng với tất cả các case và khớp với bất kỳ trường hợp mới nào được thêm vào enum. Nó sẽ tạo ra một cảnh báo của trình biên dịch cho những case mới được thêm vào enum. Từ đó, bạn có thể quyết định nên thực hiện hành động nào cho các case mới được thêm vào. Điều này khác với việc sử dụng case default: khi có cập nhật thay đổi mới một case nào đó trong enum mà chúng ta đã dùng thì thèn này sẽ không cảnh báo cho chúng ta gì cả, Vì vậy mà chúng ta chẳng biết rằng enum này có các case mới cần được dùng.

Frozen trong enums

Sự thay đổi các case trong một enum nào đó cũng chính là khái niệm về một frozen(Đóng băng) trong enum, Có nghĩa là một enum nào đó sẽ không thay đổi or cập nhật thêm các case nào nữa thì được gọi là frozen enum. Nó chỉ áp dụng cho C, hoặc Objective-C, giờ thì Swift cũng có. Một ví dụ từ thư viện chuẩn là ComparisonResult. Đây là định nghĩa Objective-C:

Ở đây chỉ có ba kết quả có thể để so sánh, vì vậy enum này sẽ không bao giờ thay đổi nữa. và nó được gọi là frozen enum

Lưu ý chú thích NS_CLOSED_ENUM thay vì chú thích NS_ENUM thông thường. Ý muốn nói là enum này sẽ không cần dùng case @unknown default trong Swift 5 khi chúng ta thực hiện tất cả các case như sau:

Nếu tác giả thư viện thêm một case mới vào frozen enum, thì trình biên dịch sẽ phàn nàn về bất kỳ các case mới được thêm vào enum đó.

Chưa frozen

Tôi không biết nếu Apple có kế hoạch chú thích bất kỳ enum nào trong UIKit và các framework liên quan hay không. Nhưng hầu hết các enum đó có khả năng là non-frozen, nhưng cũng có một số trường hợp frozen.

Ví dụ: Stack View axis là một enum UILayoutConstraintAxis vẫn non-frozen trong iOS 12. Ở đây, header file trong Objective-C là NS_ENUM:

Điều này có nghĩa là nếu bạn muốn Switch stack view axis có thêm case mới thì bạn cần cho phép khả năng thêm case trong tương lai:

Có lẽ Apple sẽ thay đổi điều này thành NS_CLOSED_ENUM hoặc có thể các chế độ Stack View sẽ có trục thứ ba trong iOS 13?

Tóm lai

  • Thứ nhất, không có gì thay đổi đối với enum Swift của riêng bạn. Bạn không cần phải bắt đầu @unknown default: trong mã của bạn khi bạn dùng switch trong Swift 5. Xcode sẽ cảnh báo bạn cần phải hành động ở đâu.
  • Thay đổi này chỉ quan trọng đối với các enum trong kiểu C được tìm thấy trong thư viện chuẩn và các framework khác. Nó sẽ nhắc cho developer biết về một số thay đổi trong enum.
  • Nếu Switch của bạn bao gồm một cases default: thì không có gì thay đổi.
  • Một Switch tất cả các case của một non-frozen enum kiểu C bao gồm tất cả các trường hợp đã biết (không có case default:) thì chúng ta sẽ nhận được một cảnh báo khi code trong Swift 5.
  • Chấp nhận sửa lỗi Xcode để thêm case@unknown default: để tắt cảnh báo.

Cảm ơn các bạn đã đọc và tham khảo bài này, nếu bạn thấy hay và hữu ích, xin vui lòng like fanpage cafedev để ủng hộ, Cảm ơn các bạn nhiều.

Đăng ký kênh youtube để ủng hộ Cafedev nha các bạn, Thanks you!