RxSwift: Bài 3 - Disposing and terminating
swift
68
RxSwift
20
Male avatar

Bùi Khánh Duy viết ngày 30/06/2018

RxSwift: Bài 3 - Disposing and terminating

=====
Updated ngày 30/06

Updated một chút: Vì những bất tiện và không rõ ràng về thông tin của kipalog, mình mới dọn về nhà mới ở đây, thoải mái, đẹp đẽ rõ ràng hơn kipalog. Mong các bạn có thể theo dõi tại trang web của mình để cập nhật thêm nha

Mình mới viết một loạt bài về chủ đề Clean Architecture và Service Locator. Các bạn có thể theo dõi.
Page trên facebook ở đây: ở đây

=====
1. Đặt vấn đề:
Nhắc lại là 1 observable sẽ không làm bất kì điều gì cho đến khi nó nhận một subscribe. Cái việc subscription này sẽ trigger hay báo hiệu cho một observable để bắt đầu phát ra các events, cứ thế cho đến khi nó phát ra sự kiện .error hoặc .completed rồi mới xong. Thực tế thì ta có thể làm việc này thủ công để khiến cho observable phải kết thúc bằng cách kết thúc tất cả các subscribe.

Vẫn trong ví dụ của bài 1, 2, ta thêm đoạn code sau:
alt text

Trình tự các bước như sau:

  1. Tạo ra một observable của một vài strings.
  2. Subscribe thằng observable này, lần này ta sẽ lưu cái biến trả về Disposable cho 1 local constant (đặt tên là subscription)
  3. Print ra các emit trong cái handler.
  4. Để cancel đàng hoàng một subscription, gọi dispose() nó là được. Sau khi cancel cái subscription này (hay nói cách khác là dispose nó), cái observable này hiện tại sẽ ngưng emit ra các events.

Quản lí từng subscription riêng biệt nhìn khá nghiệp dư nên RxSwift đã có thêm cho ta 1 cái gọi là DisposeBag. Cái này dễ giữ các disposables, mà được add trong dispose(to: DisposeBag), và nó sẽ gọi dispose() mỗi khi subscribe này chuẩn bị deallocated.
alt text

Dưới đây là cách mà disposable code hoạt động:

  • Tạo ra một disposeBag
  • Tạo ra một observable
  • Subscribe đến observable và print out ra cái giá trị được emit
  • Add cái giá trị disposable đc trả về vào cái disposeBag

Đây là pattern bạn sẽ dùng rất nhiều: Tạo ra observable rồi subscribe nó và add cái subscription vào 1 disposeBag

Tại sao lại lo lắng về vấn đề này ? Nếu bạn quên add cái subscription vào dispose bag hay add nó bằng manual hay cách nào khác khiến cho observable kết thúc ở nhiều chỗ khác nhau dẫn đến leak memory.

2. Create operator
Có một cách để lôi ra các events mà observable sẽ emit đến subscribers là create operator.
alt text
Ở đây take note 1 chút về return Disposable, Disposables.create() là một empty disposable để ai subscribe sẽ có disposable mà trả về.
Trước hết, ta xem thử create có gì trong đó:
alt text

Cái create operator này sẽ nhận 1 parameter là subscribe, nhiệm vụ của nó là tiến hành gọi observable. Hay nói cách khác, nó defines các event mà sẽ được emit đến subscribers. Subscribe này là 1 escaping closure mà lấy 1 AnyObserver và trả về 1 Disposable.

AnyObserver là 1 generic type giúp cho việc add các giá trị này vào observable sequence được dễ dàng hơn, và chúng sau đó sẽ được emit đến các subscribers

The subscribe parameter is an escaping closure that takes an AnyObserver and returns a Disposable. AnyObserver is a generic type that facilitates adding values onto an observable sequence, which will then be emitted to subscribers. Change the implementation of create to the following:

Nhìn vào các đoạn code trên, bạn xem thử liệu onNext(?) có được gọi không? Dĩ nhiên là không, bởi vì observable đã phát ra .completed event. Ta check thử bằng cách sau:
alt text

Và kết quả sẽ là:
alt text

3. Trường hợp leak memory
Bây giờ, giả sử ta có lỗi thì sao? Add 1 enum ở ngoài class như sau:
alt text

Sau đó add thêm error giữa onNext và onComplete
alt text

Kết quả sẽ là:
alt text

Rõ ràng bạn thấy nó gọi Error ra và kết thúc, onCompleted không hề được gọi trong trường hợp này.

Bây giờ ta giả sử bạn ko có hàm onError và onCompleted cũng như không có disposeBag thì chuyện gì sẽ xảy ra ?
alt text

Kết quả là observable không bao giờ kết thúc và disposable cũng không bao giờ bị disposed dẫn đến tình trạng memory leak
alt text

3. Observable factories
Thay vì tạo ra 1 observable mà đi chờ đợi xung quanh xem có ai subscribe không, ta có thể tạo observable factories mà nó phát ra một observable cho từng subscriber

Xem đoạn code dưới đây:
alt text

Mình xin giải thích một chút:

  • Tạo ra một cờ Bool để thay đổi qua lại giữa true/ false
  • Tạo ra 1 Observable của factory Int mà sử dụng deferred operator
  • Lật cờ Bool- cái này sẽ được gọi mỗi khi factory được subscribe
  • Return các data tương ứng với kết quả của flip

Thực sự, observable factory không khác mấy so với observable mà ta đã biết ở các bài trước. Thêm đoạn code này vào để check results:

alt text

Và kết quả là:
alt text

Mỗi lần bạn subscribe đến factory, bạn sẽ nhận đc 1 observable mà flip sẽ được lật lại. Bạn lấy được 123, 456, 123, 456, cứ lập đi lập lại mỗi khi có 1 subscription đc tạo ra.

Như vậy, mình đã xong bài 3.

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

Male avatar

Bùi Khánh Duy

29 bài viết.
10 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
Male avatar
3 3
RxSwift: Bài 1 Observable và Just, Of, From ===== Updated ngày 30/06 Updated một chút: Vì những bất tiện và không rõ ràng về thông tin của kipalo...
Bùi Khánh Duy viết 5 tháng trước
3 3
Male avatar
3 0
Autolayout và lifecycle trong IOS ===== Updated ngày 30/06 Updated một chút: Vì những bất tiện và không rõ ràng về thông tin của kipalog, mình mớ...
Bùi Khánh Duy viết 3 tháng trước
3 0
Male avatar
2 3
RxSwift: Bài 2 Subscribing to observables ===== Updated ngày 30/06 Updated một chút: Vì những bất tiện và không rõ ràng về thông tin của kipalog,...
Bùi Khánh Duy viết 5 tháng trước
2 3
Bài viết liên quan
White
11 4
(Link) (Link) (Link) Ở 2 phần tut trước, mình đã hướng dẫn khá chi tiết cách viết một ứng dụng camera có tích hợp chức năng nhận diện khuôn mặ...
HoangPH viết 3 năm trước
11 4
Male avatar
0 0
RxSwift: Bài 6: RxCocoa (Part 4) Units ===== Updated ngày 30/06 Updated một chút: Vì những bất tiện và không rõ ràng về thông tin của kipalog, mì...
Bùi Khánh Duy viết 5 tháng trước
0 0
White
2 0
Có nhiều cách viết blog công nghệ hơn là làm bánh hay làm tình. Những ngày này Hà Nội mưa liên miên, được cái mát giời, mình lại tức cảnh sinh tìn...
VietHQ viết 1 năm trước
2 0
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


Male avatar
{{userFollowed ? 'Following' : 'Follow'}}
29 bài viết.
10 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!