Người nghe sự kiện nên được tổ chức trong tài liệu tham khảo yếu?


9

Thông thường người nghe sự kiện không nên sống lâu hơn đối tượng đã đăng ký chúng.

Điều đó có nghĩa là các trình lắng nghe sự kiện nên được giữ bởi các tham chiếu yếu theo mặc định (được lưu trữ trong các bộ sưu tập yếu bởi các trình nghe đối tượng được đăng ký trên)?

Có trường hợp hợp lệ khi người nghe nên tồn tại lâu hơn người tạo ra nó?

Hoặc có thể tình huống như vậy là một sai lầm và nó không nên được cho phép?


Các tham chiếu yếu thường được đại diện bởi các thể hiện và các thể hiện này cũng có thể tích lũy đến điểm mà chúng phải được thu thập dưới dạng rác. Vì vậy, nó không phải là một bữa ăn trưa miễn phí. Logic tương tự xóa các tham chiếu yếu có thể xóa các tham chiếu mạnh.
Frank Hileman

Câu trả lời:


7

Tại sao người nghe sự kiện không tồn tại lâu hơn đối tượng đã đăng ký chúng? Có vẻ như bạn đang giả sử người nghe sự kiện nên đăng ký bằng các phương thức điều khiển (nếu chúng ta lấy ví dụ GUI) - hay chính xác hơn là các phương thức của các đối tượng của các lớp kế thừa các điều khiển của bộ công cụ GUI. Đó không phải là một điều cần thiết - ví dụ, bạn có thể sử dụng một đối tượng chuyên biệt để đăng ký người nghe sự kiện và bỏ qua đối tượng đó sau đó.

Ngoài ra, nếu người nghe sự kiện được giới thiệu yếu, bạn sẽ phải thực sự giữ tài liệu tham khảo cho họ ngay cả khi bạn không bao giờ sử dụng tài liệu tham khảo đó. Không làm như vậy sẽ làm cho người nghe được thu thập tại một thời điểm ngẫu nhiên. Vì vậy, chúng tôi nhận được một lỗi đó là

  • Dễ dàng tạo nhầm (tất cả những gì bạn phải làm là quên lưu trữ một đối tượng trong một biến tham chiếu mà bạn sẽ không bao giờ sử dụng).
  • Khó để ý (bạn sẽ chỉ gặp lỗi đó nếu GC thu thập đối tượng đó).
  • Khó gỡ lỗi (trong phiên gỡ lỗi - luôn hoạt động giống như phiên phát hành - bạn sẽ chỉ gặp phải lỗi đó nếu GC thu thập đối tượng).

Và nếu tránh được lỗi đó không đủ khuyến khích, thì đây là một số điều nữa:

  1. Bạn sẽ phải nghĩ ra một cái tên cho mỗi người nghe bạn tạo ra.

  2. Một số ngôn ngữ sử dụng anlysis tĩnh sẽ tạo cảnh báo nếu bạn có trường thành viên riêng không bao giờ được viết hoặc không bao giờ được đọc. Bạn sẽ phải sử dụng một cơ chế để ghi đè lên điều đó.

  3. Người nghe sự kiện làm một cái gì đó, và một khi đối tượng có tham chiếu mạnh được thu thập, nó sẽ ngừng làm điều đó. Bây giờ bạn có một cái gì đó ảnh hưởng đến trạng thái của chương trình và phụ thuộc vào GC - có nghĩa là GC ảnh hưởng đến trạng thái cụ thể của chương trình. Và đây là BAD !

  4. Xử lý các tham chiếu yếu chậm hơn, vì bạn có một mức độ gián tiếp khác và vì bạn cần kiểm tra xem tham chiếu đã được thu thập chưa. Điều này sẽ không thành vấn đề nếu có người nghe sự kiện trong các tài liệu tham khảo yếu là cần thiết - nhưng không phải vậy!


5

Nói chung, có, nên sử dụng tài liệu tham khảo yếu. Nhưng trước tiên, chúng ta phải hiểu rõ ý của bạn về những người nghe sự kiện trên mạng.

Gọi lại

Trong một số kiểu lập trình, đặc biệt là trong bối cảnh của các hoạt động không đồng bộ, thông thường đại diện cho một phần của phép tính là một cuộc gọi lại được thực hiện trong một sự kiện nhất định. Ví dụ: Promise[ 1 ] có thể có thenphương thức đăng ký gọi lại sau khi hoàn thành bước trước đó:

promise =
    Promise.new(async_task)                # - kick off a task
    .then(value => operation_on(value))    # - queue other operations
    .then(value => other_operation(value)) #   that get executed on completion
... # do other stuff in the meanwhile
# later:
result = promise.value # block for the result

Ở đây, các cuộc gọi lại được đăng ký thenphải được tổ chức bởi các tham chiếu mạnh, vì lời hứa (nguồn sự kiện) là đối tượng duy nhất giữ tham chiếu đến cuộc gọi lại. Đây không phải là một vấn đề vì bản thân lời hứa có thời hạn sử dụng và sẽ được thu gom rác sau khi chuỗi lời hứa hoàn thành.

Mẫu quan sát

Trong mẫu quan sát viên, một đối tượng có một danh sách các quan sát viên phụ thuộc. Khi đối tượng vào trạng thái nào đó, người quan sát được thông báo theo giao diện nào đó. Người quan sát có thể được thêm vào và xóa khỏi chủ đề. Những người quan sát này không tồn tại trong một khoảng trống ngữ nghĩa, nhưng đang chờ đợi các sự kiện cho mục đích nào đó.

Nếu mục đích này không còn tồn tại, các quan sát viên nên được loại bỏ khỏi chủ đề. Ngay cả trong các ngôn ngữ được thu gom rác, việc loại bỏ này có thể phải được thực hiện thủ công. Nếu chúng ta không xóa một người quan sát, nó sẽ được giữ sống thông qua tham chiếu từ chủ thể đến người quan sát và với tất cả các đối tượng mà người quan sát tham chiếu. Điều này làm lãng phí bộ nhớ và làm giảm hiệu suất vì người quan sát (bây giờ vô dụng) vẫn sẽ được thông báo.

Tài liệu tham khảo yếu khắc phục rò rỉ bộ nhớ này, vì chúng cho phép người quan sát được thu gom rác. Khi đối tượng đi xung quanh để thông báo cho tất cả các nhà quan sát và thấy rằng một trong những tài liệu tham khảo yếu cho người quan sát là trống rỗng, tài liệu tham khảo đó có thể được gỡ bỏ một cách an toàn. Ngoài ra, các tham chiếu yếu có thể được thực hiện theo cách cho phép đối tượng đăng ký một cuộc gọi lại dọn dẹp sẽ loại bỏ người quan sát khi thu thập.

Nhưng lưu ý rằng các tài liệu tham khảo yếu chỉ là một hỗ trợ ban nhạc hạn chế thiệt hại bằng cách quên loại bỏ một người quan sát. Giải pháp chính xác là đảm bảo rằng người quan sát được gỡ bỏ khi không còn cần thiết. Các tùy chọn bao gồm:

  • Làm thủ công, nhưng điều đó dễ bị lỗi.

  • Sử dụng một cái gì đó giống như dùng thử với tài nguyên trong Java hoặc usingtrong C #.

  • Phá hủy quyết định, chẳng hạn như thông qua thành ngữ RAII. Lưu ý rằng trong một ngôn ngữ có bộ sưu tập rác xác định, điều này vẫn có thể yêu cầu các tham chiếu yếu từ chủ thể đến người quan sát để kích hoạt hàm hủy.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.