2009-02-24 33 views
12

Tôi là một phần trong quá trình phát triển của tôi để theo dõi tình trạng lỗi và rò rỉ bộ nhớ. Là một chiến lược, bạn có đặt bất kỳ thông điệp NSLog hoặc thông báo nào về một số thông báo như vậy vào didReceiveMemoryWarning: không? Tài liệu cho phương pháp này khá thưa thớt. Là nó chính xác để nói rằng trước khi một vụ tai nạn sẽ xảy ra, UIViewController sẽ kích hoạt phương pháp đó? Đó có phải là điểm khởi đầu trước khi tiếp tục với Nhạc cụ không?iOS: tính hữu ích của didReceiveMemoryWarning:

Trả lời

28

OK, một số điều cần lưu ý:

  • didReceiveMemoryWarning sẽ được gọi trước khi một vụ tai nạn out-of-bộ nhớ. Không phải các sự cố khác. Nếu bạn xử lý cảnh báo đúng cách và giải phóng bộ nhớ, thì bạn có thể tránh tình trạng bộ nhớ ngoài và không bị lỗi.
  • Bạn có thể tự kích hoạt cảnh báo bộ nhớ trong trình mô phỏng trong menu Phần cứng. Rất khuyên bạn nên làm điều này để kiểm tra việc xử lý của bạn của didReceiveMemoryWarning.
  • Công cụ giúp bạn gỡ lỗi rò rỉ (mặc dù không phải tất cả chúng) - nó không thực sự hữu ích cho các sự cố.
  • Không, tôi không đích thân sử dụng NSLog - Tôi chỉ phá vỡ cảnh báo bộ nhớ khi tôi đang gỡ lỗi.
+0

Hi Airsource, tôi có thể hỏi 'Trình mô phỏng -> Phần cứng -> Mô phỏng Cảnh báo Bộ nhớ' được sử dụng để làm gì? Bất cứ khi nào tôi nhấp vào nó, tôi chỉ nhận được thông báo "Đã nhận được cảnh báo bộ nhớ mô phỏng". trong bảng điều khiển. Làm cách nào để sử dụng nó để 'xóa các vấn đề'? Cảm ơn. – lionfly

+0

@lionfly - bạn nên, để đáp ứng với một cảnh báo bộ nhớ, giải phóng bộ nhớ càng nhiều càng tốt. Mô phỏng cảnh báo bộ nhớ cho phép bạn kiểm tra (và gỡ lỗi) đường dẫn mã đó. –

3

Mục đích của didReceiveMemoryWarning là để cho bạn cơ hội giải phóng bộ nhớ hoặc chế độ xem pop để tránh sự cố. Bạn sẽ không nhận được nó ở bất kỳ điểm dự đoán nào vì nó phụ thuộc vào những gì người dùng đang làm. Ví dụ, nếu người dùng đang nghe iPod, sẽ có ít bộ nhớ hơn và bạn sẽ sớm nhận được nó.

Nguyên tắc chung là bạn có khoảng 8MB RAM để làm việc. Khi bạn đến gần đó, bạn có thể mong đợi sự kiện được nâng lên. Nếu bạn đang chiếm nhiều RAM, bạn nên có kế hoạch để làm điều gì đó về nó.

4

CẬP NHẬT Do iOS 6, UIViewController lượt xem không còn được tải để phản hồi cảnh báo bộ nhớ. Thay vào đó, hãy cố gắng hết sức để giải phóng bất kỳ tài nguyên nào bạn có thể tạo lại hợp lý (ví dụ: dữ liệu được lưu trong bộ nhớ cache) khi gọi didReceiveMemoryWarning.

CẬP NHẬT
Tôi đã viết câu trả lời ban đầu khi tôi là một thanh niên giận dữ; thời gian đã thay đổi và về cơ bản, nó sai.

Nếu bạn có ứng dụng có bộ điều khiển chế độ xem đơn và bạn nhận được cảnh báo bộ nhớ, bạn không thể thực hiện nhiều thao tác này. Nhưng mọi thứ thay đổi đáng kể nếu bạn có nhiều bộ điều khiển chế độ xem, vì bạn có thể bỏ tất cả tất cả trạng thái được kết hợp với bộ điều khiển ngoài cùng phía trước. Trong thực tế, [UIViewController didReceiveMemoryWarning] sẽ đưa bạn đi đúng hướng bằng cách dỡ bỏ các chế độ xem không hiển thị cho bạn (bất ngờ!). Khi bộ điều khiển xem trước cùng bị loại bỏ, chế độ xem cơ bản được tải lại và hầu hết người dùng chỉ nên biết về sự chậm trễ mặc dù nội bộ ứng dụng của bạn có thể đã khởi động lại hoàn toàn.

Đây không phải là một số chi tiết bạn có thể dễ dàng trang bị thêm, bạn cần lưu ý đến việc sử dụng bộ nhớ ngay từ đầu và thiết kế ứng dụng multiview của bạn thành các phần UIViewController gọn gàng. Trong thực tế nó là giá trị giữ mã của bạn tương thích với các mô phỏng chỉ để sử dụng tính năng cảnh báo bộ nhớ của nó.

Khi bộ nhớ dồi dào, không có gì được tải xuống và mọi thứ đều mượt mà, và khi bộ nhớ ở mức thấp, hãy tiếp tục làm việc, mặc dù chậm hơn. Bây giờ tôi muốn nói rằng giải pháp này cho vấn đề bộ nhớ hữu hạn là lý tưởng.

Để tận dụng này lừa bộ nhớ phòng khách, quá tải UIViewController phương pháp viewDidLoad, viewDidUnload, và viewWillUnload (iOS5, hữu ích nếu dỡ nhà nước đòi hỏi tầm nhìn của bạn vẫn tồn tại, ví dụ như nếu bạn không muốn bị rò rỉ OpenGL của bạn kết cấu & hiển thị bộ đệm, trên iOS4 bạn có thể mô phỏng điều này bằng cách quá tải didReceiveMemoryWarning và theo dõi khả năng hiển thị của chế độ xem của bạn).

ORIGINAL, THÊM BILIOUS ĐÁP

didReceiveMemoryWarning là hoàn toàn vô dụng.

Không đảm bảo rằng nếu bạn giải phóng bộ nhớ (ngay cả tất cả) bạn sẽ không bị giết.

Theo kinh nghiệm cay đắng của tôi nó thường làm việc như thế này trên 2.x/3.0:

  1. mediaserverd rò rỉ một loạt các bộ nhớ

  2. ứng dụng của tôi bị giết

Thật không may , người gặt không bao giờ nghĩ đến việc giết mediaserverd.

Vì vậy, nếu sử dụng bộ nhớ không phải là lỗi của bạn, bạn đã thực sự chỉ có hai lựa chọn:

  1. yêu cầu người dùng khởi động lại (sử dụng giả định đó là lỗi của bạn, viết một bài đánh giá gay gắt)

  2. hy vọng các tai nạn thủ phạm (mediaserverd thường buộc!)

+0

Thời gian diễu hành trên. viewDidUnload hiện không được chấp nhận với các ghi chú này, "Chế độ xem không còn bị xóa trong điều kiện bộ nhớ thấp và do đó phương pháp này không bao giờ được gọi." và "Trong iOS 6 trở lên, việc xóa tham chiếu đến chế độ xem và các đối tượng khác trong trình điều khiển chế độ xem của bạn là không cần thiết."- [source] (https://developer.apple.com/reference/uikit/uiviewcontroller/1621383-viewdidunload?language=objc) – jk7

+0

Tôi đã nghĩ đến việc cập nhật câu trả lời này chỉ vào một ngày khác! –

5

Nếu người dùng để lại một số ứng dụng mở, bạn sẽ có rất ít bộ nhớ tại dispos của bạn al. Vì vậy, đôi khi didReceiveMemoryWarning chỉ có thể được hệ thống gọi sau khi sử dụng 1 MB.

Hệ thống gọi phương thức này trên tất cả các bộ điều khiển chế độ xem của bạn, nếu bạn đặt NSLog trong mỗi bộ điều khiển chế độ xem, bạn sẽ thấy điều đó.

Sau đó, phương pháp tự động viewDidUnload sẽ được hệ thống gọi trên tất cả các bộ điều khiển chế độ xem của bạn (không phải dealloc). Vì vậy, bạn phải đặt tất cả các hướng dẫn deallocation của bạn trong đó.

Bạn phải thực hiện rất nhiều thử nghiệm vì nếu ứng dụng của bạn phức tạp, bạn sẽ phải đối mặt với rất nhiều sự cố trước khi quản lý tốt.

Các vấn đề liên quan