2010-09-08 24 views
6

Tôi có một ứng dụng sử dụng NSOperations để quản lý các cuộc gọi dịch vụ tới một API web (các cuộc gọi được dựa trên CURLOperation in Jon Wight's touchcode).Tại sao NSOperationQueue trên iPhone OS 3.1 giữ lại các hoạt động bị hủy bỏ (và phát hành) lâu dài?

Có một cuộc gọi nhất định tải xuống vị trí bản đồ khi trung tâm của chế độ xem bản đồ thay đổi đáng kể; vì những thứ này có thể xếp chồng lên nhau nhanh chóng, nếu bạn di chuyển bản đồ xung quanh, tôi cố gắng triệt để hủy các hoạt động cũ. Nó hoạt động tốt trên 4.0. Tuy nhiên, trên 3.1, có vẻ như trong một số trường hợp, hàng đợi vận hành sẽ giữ các hoạt động bị hủy bỏ (và được giải phóng), gây ra sự cố khi nó đến vị trí mà chúng phải ở trong hàng đợi.

Đây là hình minh họa.

Tôi bắt đầu với một cuộc gọi dịch vụ tương đối nặng trong hàng đợi:

  1. MyLongRunningOp 0x1

Người dùng điều hướng tới bản đồ. Hàng đợi bây giờ trông như thế này:

  1. MyLongRunningOp 0x1
  2. MyMapOp 0x2

Họ di chuyển bản đồ, mà hủy 0x2 MyMapOp và thêm 0x3 MyMapOp:

  1. MyLongRunningOp 0x1
  2. MyMapOp 0x3

MyMapOp 0x2 hiện đã được phát hành, vì nó đã bị xóa khỏi hàng đợi. Bây giờ, MyLongRunningOp 0x1 hoàn tất. Trong các cuộc gọi lại của KVO để thiết lập khóa isFinished trên MyLongRunningOp, tôi thấy hàng đợi vận hành xử lý thông báo và thử thêm MyMapOp 0x2 vào một số NSArray. Đương nhiên, với NSZombies kích hoạt,

[MyMapOp retain]: message sent to deallocated instance 0x2 

Dường như NSOperationQueue được bằng cách nào đó treo vào một con trỏ đến hủy/hoạt động phát hành, và cố gắng để kích hoạt nó sau ca phẫu thuật trước khi kết thúc.

Tôi chưa thể tái tạo hành vi này trên 4.0, vì vậy tôi tin rằng đó là lỗi 3.1.

Tôi đang gặp nhiều rắc rối khi làm việc xung quanh - theo như tôi có thể nói, cách giải quyết duy nhất là không bao giờ hủy các hoạt động của tôi, điều này tạo ra trải nghiệm tối ưu khi mạng bị lỗi.

Có ai khác có kinh nghiệm này không? Ý tưởng nào?

Trả lời

1

Tôi đã có (những gì tôi tin là) một vấn đề tương tự khi sử dụng KVO trên NSOperations.

Chỉ cần đọc mô tả của bạn, bản năng đầu tiên của tôi sẽ là kiểm tra các quy tắc cho hàng đợi hoạt động. Có thể là một khi bạn đưa nó vào hàng đợi, hàng đợi phải thừa nhận quyền sở hữu và do đó bạn không nên tự giải phóng nó? (Không chắc bạn có hay không).

Từ kinh nghiệm cá nhân của tôi, và có thể nó sẽ giúp hay không:

1) Khi bạn hủy một op, loại bỏ các nhà quan sát KVO từ nó. Tôi đã có nó xảy ra KVO không nhận được unlinked khi hai bên bị xóa.

2) Lưu ý rằng các cuộc gọi lại của KVO chạy trong cùng một luồng với NSOperation. Vì vậy, nó có thể cho một đối tượng để đi ra khỏi phạm vi giữa thời gian bạn bắt đầu hoạt động và một cuộc gọi lại KVO.

Tôi có thể cung cấp cho bạn thêm một số trợ giúp nếu bạn đăng mã. Hy vọng rằng ở trên đã có ích cho bạn!

+0

Tôi tin điều này là chính xác. Thay vì loại bỏ nó khỏi hàng đợi, bạn chỉ cần gửi một thông điệp -ancel, mà không giải phóng nó hoặc loại bỏ nó khỏi hàng đợi - nhưng khi nó được xếp vào đầu hàng đợi, nó sẽ bị bỏ qua và giải phóng. – makdad

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