- vừa được xem lúc

Convenience cases - Một cách sử dụng Enum rất hay nhưng ít người biết

0 0 18

Người đăng: Hà Tuấn Thịnh

Theo Viblo Asia

Giả sử chúng ta đang xây dựng một ứng dụng cần nhiều animation. Chúng ta define một enum RepeatMode để điều khiển số lần animation lặp lại trước khi bị remove.

Cách implement đơn giản nhất có lẽ là sử dụng một biến Int để thể hiện số lần animation lặp lại, nhưng chúng ta lại không thích thế, mà sẽ làm như sau để nhấn mạnh vào những kiểu lặp lại hay được sử dụng, chẳng hạn 1 lần (once) hay không bao giờ (never):

extension Animation { enum RepeatMode: Equatable { case once case times(Int) case never case forever }
}

Tuy nhìn qua thì API này trông có vẻ rất gọn gàng (vì từ ngoài chúng ta chỉ cần sử dụng cú pháp của enum để điều khiển số lần repeat, chẳng hạn .times(5).forever), nhưng đoạn code bên trong để xử lý các trường hợp này thì lại rất cồng kềnh, vì chúng ta cần xử lý từng case của RepeatMode riêng, mặc dù logic khá là giống nhau:

func animationDidFinish(_ animation: Animation) { switch animation.repeatMode { case .once: if animation.playCount == 1 { startAnimation(animation) } case .times(let times): if animation.playCount <= times { startAnimation(animation) } case .never: break case .forever: startAnimation(animation) }
}

Cần phải code lại đoạn này ngay, chứ để thế này ai mà đọc được thì ngại chết. Và để xử đẹp vụ này, chúng ta có thể sử dụng convenience cases - một cách dùng enum khá ít người biết.

Cách dùng như sau:

Đầu tiên, chúng ta giảm lượng case của enum RepeatMode xuống còn 2 case, một case cho phép truyền vào một biến thể hiện số lần repeat, và một case để repeat forever.

extension Animation { enum RepeatMode: Equatable { case times(Int) case forever }
}

Sau đó, chúng ta extense Animation.RepeatMode:

extension Animation.RepeatMode { static var once: Self { .times(1) } static var never: Self { .times(0) }
}

Khi làm thế này, thì từ ngoài nhìn vào API Animation của chúng ta vẫn giống hệt như cũ, và cả đoạn code xử lý bên trong của chúng ta cũng chẳng phải thay đổi gì (nếu chúng ta để nguyên nó vẫn chạy tốt).

Tất nhiên nếu bạn giữ nguyên đoạn switch như cũ, và truyền vào hàm animationDidFinish một Animation có repeatMode == .once, thì hàm switch sẽ nhảy vào case .once.

Đây là lúc câu chuyện trở nên thú vị, bạn hãy thử sửa lại đoạn switch thành như sau:

func animationDidFinish(_ animation: Animation) { switch animation.repeatMode { case .times(let times): if animation.playCount <= times { startAnimation(animation) } case .forever: startAnimation(animation) }
}

Và run thử, để thấy code vẫn compile và chạy ầm ầm, dù đã bỏ đi 2 case trong đoạn switch kia.

Lúc này nếu bạn truyền một Animation với repeatMode == .once vào hàm animationDidFinish, thì đoạn switch kia sẽ nhảy vào case .times(1).

Có thể thấy convenience cases có thể giúp code của chúng ta vừa ngắn gọn, vừa dễ hiểu hơn mà lại không làm thay đổi mục đích và cách sử dụng ban đầu.

Hi vọng bài viết của mình sẽ giúp các bạn có thêm một công cụ hữu ích khi code Swift.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Swift: Tạo custom phép toán tử (Operator) của riêng bạn!

Swift cho phép bạn tạo các toán tử có thể tùy chỉnh của riêng bạn. Điều này đặc biệt hữu ích khi bạn xử lý các loại dữ liệu của riêng mình. Operator Types in Swift. Có năm loại toán tử chính trong Swift.

0 0 45

- vừa được xem lúc

Code ngắn gọn hơn với OptionSet trong Swift

. Nếu bạn muốn biết cách xử lý với Bitmasks trong Swift hay là bạn đã từng nghe đến OptionSet chưa? Bài viết này sẽ giúp bạn hiểu hơn về điều đó . 1.

0 0 26

- vừa được xem lúc

Chương 6 Protocol oriented programming.

Cuốn sách này là về lập trình hướng protocol. Khi Apple thông báo swift 2 ở WWDC 2015.

0 0 28

- vừa được xem lúc

Ví dụ về UIActivityViewController

Trên iOS, UIActivityViewController cung cấp giao diện thống nhất để người dùng chia sẻ và thực hiện các hành động trên văn bản, hình ảnh, URL và các mục khác trong ứng dụng. let string = "Hello, world!". let url = URL(string: "https://nshipster.com").

0 0 45

- vừa được xem lúc

Quản lý self và cancellable trong Combine.

. . Công việc quản lý bộ nhớ memory management thường trở nên phức tạp khi chúng ta thực hiện các tác vụ bất đồng bộ asynchronous vì chúng ta thường phải lưu giữ một số object nằm ngoài scope mà object được define trong khi vẫn phải đảm bảo được việc giải phóng object đó được thực hiện đúng quy trìn

0 0 28

- vừa được xem lúc

[SWIFT] Sử dụng Dependency Injection với Storyboards

1. Lời mở đầu:.

0 0 30