2013-03-08 18 views
8

Tôi sợ rằng việc đặt câu hỏi này có thể dẫn đến một số nhược điểm, nhưng sau khi thực hiện một số nghiên cứu không thỏa mãn, tôi đã quyết định mạo hiểm và hỏi thêm người ...Loại rò rỉ bộ nhớ nào XCode Analyzer có thể không nhận thấy?

Có nhiều câu hỏi ở đây đề cập đến một số các sự cố được kết nối với Công cụ Analayzer XCode. Nó có vẻ là giải pháp rất hữu ích. Nhưng tôi muốn hỏi bạn - là người mới bắt đầu trong thế giới iOS - loại công cụ quản lý bộ nhớ nào không thể được chú ý bởi công cụ này.

Nói cách khác, có bất kỳ khía cạnh quản lý bộ nhớ chung nào, về những người mới bắt đầu iOS nên nghĩ "Ồ, hãy cẩn thận với điều đó, vì trong trường hợp này XCode Analyzer có thể không cảnh báo bạn về lỗi của bạn" ...

Ví dụ, tôi đã tìm thấy ở đây Why cannot XCode static analyzer detect un-released retained properties? rằng:

(...) phân tích có thể không đáng tin cậy phát hiện giữ lại các vấn đề/release trên ranh giới phương/thư viện (...)

Nghe có vẻ giống như một gợi ý tốt để xem xét, nhưng có thể bạn biết về một số vấn đề phổ biến khác ...

+1

Chỉ vì một công cụ có thể phát hiện rò rỉ không có nghĩa là bạn không nên suy nghĩ về quản lý bộ nhớ ít cẩn thận hơn. Đó là một công cụ, không thay thế suy nghĩ cẩn thận. –

Trả lời

7

Máy phân tích rất giỏi trong việc tìm kiếm các rò rỉ thông thường làm cho các lập trình viên mới viết mã không phải ARC (thất bại) hãy gọi release, trả lại các đối tượng có số lần giữ lại sai, v.v.).

Theo kinh nghiệm của tôi, có một vài loại vấn đề bộ nhớ nó không tìm thấy:

  • Nó có thể không thường xác định strong reference cycles (còn gọi là retain cycles). Ví dụ, bạn thêm NSTimer lặp lại vào bộ điều khiển chế độ xem, không biết rằng bộ hẹn giờ duy trì tham chiếu mạnh đến bộ điều khiển chế độ xem và nếu bạn không invalidate bộ hẹn giờ (hoặc làm sai vị trí, chẳng hạn như phương pháp dealloc) , không phải bộ điều khiển xem cũng như bộ hẹn giờ sẽ không được phát hành.

  • Nó không thể tìm thấy lỗi logic tròn. Ví dụ, nếu bạn có một số tham chiếu vòng tròn nơi bộ điều khiển xem A trình bày bộ điều khiển xem B, do đó trình bày một bản sao mới của A (thay vì loại bỏ/popping để lấy lại A).

  • Nó không thể tìm thấy nhiều vấn đề bộ nhớ đếm không tham chiếu. Mặc dù nó hoạt động tốt hơn trong việc xử lý các chức năng của Core Foundation, nếu bạn có mã đang thực hiện phân bổ bộ nhớ thủ công (chẳng hạn như thông qua mallocfree), thì máy phân tích tĩnh có thể bị hạn chế sử dụng. Điều này cũng đúng bất cứ khi nào bạn sử dụng mã đếm không tham chiếu (ví dụ: bạn sử dụng SQLite sqlite3_prepare_v2 và không gọi sqlite3_finalize).

Tôi chắc chắn đó không phải là danh sách đầy đủ những gì nó không tìm thấy, nhưng đó là những vấn đề phổ biến mà tôi thấy được hỏi về Stack Overflow mà trình phân tích tĩnh sẽ bị giới hạn trợ giúp. Nhưng máy phân tích vẫn là một công cụ tuyệt vời (nó cũng tìm ra các vấn đề khác với vấn đề bộ nhớ) và đối với những cá nhân không sử dụng ARC, nó vô giá. Đã nói rằng, trong khi phân tích tĩnh là một dòng phòng thủ đầu tiên được đánh giá cao, bạn thực sự nên sử dụng các dụng cụ để tìm rò rỉ. Xem Locating Memory Issues in Your App trong Hướng dẫn sử dụng thiết bị Instruments. Đó là cách tốt nhất để xác định rò rỉ.

+0

Bạn có thể thắp sáng thêm một chút lý do tại sao nó sẽ là xấu để 'invalidate' bộ đếm thời gian của bạn trong dealloc? –

+3

@MarkBernstein 'dealloc' chỉ được gọi khi không có tham chiếu mạnh mẽ hơn cho bộ điều khiển xem. Vì vậy, bởi vì bộ đếm thời gian lặp lại duy trì một tham chiếu mạnh mẽ cho bộ điều khiển xem, nó sẽ không bao giờ được gọi. Đặt 'invalidate' trong' dealloc' là tương tự khi nói "khi không có tham chiếu mạnh mẽ hơn cho bộ điều khiển xem này, hãy tiếp tục và loại bỏ tham chiếu mạnh mẽ của bộ hẹn giờ tới bộ điều khiển chế độ xem này." Bạn thường đặt 'invalidate' vào' viewWillDisappear' hoặc một cái gì đó tương tự, tùy thuộc vào chi tiết của ứng dụng của bạn. – Rob