2011-10-13 34 views
7

Tôi đã dành thời gian gỡ lỗi một vấn đề lạ với ARC và các chức năng dealloc tùy chỉnh.Vấn đề gỡ rối Xcode và ARC (bỏ qua dealloc)

  1. Tôi subclassing NSOperation lớp
  2. tôi đặt khối hoàn thành cho hoạt động này
  3. Các hoạt động được tham chiếu bởi một tài sản mạnh mẽ của rất đối tượng phẳng (không có phương pháp, ivars tự động, hai thuộc tính mạnh mẽ) cho phép gọi đối tượng này DataRequest
  4. theo tất cả các hướng dẫn khối hoàn thành chỉ sử dụng các tham chiếu yếu cho các đối tượng địa phương (bao gồm cả chính hoạt động)
  5. trình biên dịch cũng không phân tích giải quyết mọi vấn đề
  6. DataRequest giữ tham chiếu CHỈ cho hoạt động tôi tạo và bị hủy trong khối hoàn thành hoạt động. LUÔN LUÔN bị phá hủy (dealloc luôn được thực thi)
  7. Hoạt động của tôi có một tùy chỉnh dealloc. Tôi chỉ có một cuộc gọi NSLog trong đó.

... và vấn đề là:

Nếu tôi chạy theo này trong trình gỡ lỗi, breakpoint trong dealloc không bao giờ trúng, thông điệp log không bao giờ xuất hiện. Chủ yếu là tôi nghĩ rằng các hoạt động đã bị rò rỉ.

Nếu tôi chạy công cụ này, tất cả đều ổn, bảng điều khiển hệ thống in thông báo và công cụ phân bổ báo cáo hoạt động được giải phóng khỏi ảnh chụp nhanh ngăn xếp bao gồm dealloc tùy chỉnh. Không phát hiện rò rỉ.

Tôi chắc chắn 100% tôi sử dụng cùng một cài đặt trình biên dịch để gỡ lỗi và để lập hồ sơ.

Điều khó hiểu nhất ở cuối: Nếu tôi tạo phiên bản tùy chỉnh [DataRequest dealloc] và tôi đặt self.operation = nil; cho nó - tất cả đều hoạt động tốt ngay cả từ trình gỡ lỗi.

Có ai có gợi ý nào về tùy chọn trình liên kết trình biên dịch để thử xem sự khác biệt nào không? điều này có thể là lỗi trong các công cụ của Apple (tất cả chúng ta đang ở trong vị trí đổ lỗi cho một con cá lớn vì lỗi của chúng ta không?)

... và vâng tôi đã thử với GDB và LLDB. Kết quả là như nhau - những gì có thể cho thấy một cái gì đó.

Tôi đã cố gắng để tạo ra một mẫu tối giản nhưng nó chỉ làm việc (thực sự);)

Cảm ơn

+0

Tôi đã thực hiện quan sát rất cơ bản ... nếu tôi chạy ứng dụng trên trình mô phỏng từ XCode (GDB hoặc LLDB), các thông điệp tường trình của tôi trong 'dealloc' sẽ không được in. Nếu tôi chỉ cần thoát khỏi trình gỡ rối và khởi động ứng dụng trực tiếp từ trình mô phỏng - Console.app hiển thị tất cả các tin nhắn. Không biên dịch không liên kết ở giữa. Lạ thật. – simpleone

+0

... và một kết quả đơn giản hơn ... Nếu tôi chạy ứng dụng từ XCode trong phiên gỡ lỗi - dealloc không được gọi (nhật ký không được in) nếu tôi chạy ứng dụng theo cách thủ công trong trình mô phỏng và sau đó đính kèm trình gỡ lỗi .. tất cả là như mong đợi. – simpleone

Trả lời

7

Bạn có NSZombiesEnabled? Chúng tôi đã có cùng một vấn đề và "giải quyết" nó bằng cách vô hiệu hóa NSZombies.

"sản phẩm" -> "Đề án" -> "Chỉnh sửa chương trình" -> "Chẩn đoán" -> Bỏ chọn "Enable Zombie Objects"

Tôi không chắc chắn lý do tại sao dealloc không được gọi khi NSZombies được kích hoạt (Tôi khá chắc chắn nó đã được gọi trước khi ARC).

+0

Tôi phải kiểm tra - nhưng có, tôi đã thiết lập NSZombiesEnabled. Điều này nghe có vẻ khá - và ít nhất nó đưa ra một số lời giải thích hợp lý cho hành vi khác nhau. – simpleone

+1

Tôi có thể xác nhận NSZombiesEnabled đang gây ra sự cố. Cảm ơn nhiều! – simpleone

+1

Điều này có thể xảy ra khắp nơi khi sử dụng NSZombiesEnabled với ARC, không chỉ với 'NSOperation'. Điều quan trọng nếu quan sát dealloc weirdness với ARC là để vô hiệu hóa NSZombiesEnabled (được gắn nhãn "Enabled Zombie Objects" trong Edit Schemes ...> Diagnostics tab trong Xcode 4.) –

1

Tôi đã gặp phải vấn đề tương tự như hôm nay và tôi mất khoảng 5 giờ để thấy rằng vấn đề là do NSZombies được kích hoạt trong cài đặt dự án của tôi.

Tôi cũng đồng ý rằng trước ARC, dealloc được gọi trong trường hợp này.

Sau nhiều lần kiểm tra, có vẻ như dealloc không được gọi nếu sử dụng iOS 5.x (thiết bị hoặc trình mô phỏng).

nhưng nó được gọi là một lần nữa (với Zombies kích hoạt) trong iOS 6.x (thiết bị hoặc mô phỏng)

Tôi không biết nếu sự thay đổi này là do một lỗi trong ios5 đã được vá trong iOS6, hoặc một tính năng được giới thiệu và cuộn lại.

Hy vọng rằng sẽ giúp ...

0

Tôi chạy vào cùng một loại vấn đề hiện nay nhưng vấn đề của tôi là một chu kỳ giữ lại được tạo ra bởi một khối.

Nếu bạn đang sử dụng khối:

  1. Hãy chắc chắn rằng TỰ không xuất hiện bên trong khối.
  2. Nếu bạn cần sử dụng SELF bên trong một khối, hãy sử dụng tham chiếu yếu.
  3. Đảm bảo không có macro nào bên trong khối có thể tham chiếu đến bản thân (như NSAssert).
Các vấn đề liên quan