2009-04-18 46 views
9

Tôi có một NSInvocationOperation sẽ tải xuống và phân tích cú pháp một loạt các NSXMLDocuments trong nền cho giao diện người dùng của tôi đáp ứng.Làm thế nào để ngăn chặn một NSInvocationOperation?

Nỗ lực của tôi trong việc dừng thao tác Gọi là gọi hàm hủyAllOperations của NSOperationQueue của tôi. Nhưng có vẻ như điều này sẽ không ngừng thực hiện lời gọi.

Bất kỳ ý tưởng nào về cách tôi giải quyết vấn đề này?

Trả lời

3

Việc thực hiện đối tượng NSOperation của bạn là thực sự dừng hoạt động những gì nó đang làm, dọn sạch và thoát khi được thông báo rằng nó đã bị hủy. Tin nhắn mà bạn muốn hủy bỏ tất cả các thao tác trên hàng đợi sẽ làm cho hàng đợi ngừng hoạt động các thao tác mới để chạy và sẽ gửi thông báo hủy đến bất kỳ thao tác nào hiện đang chạy.

Trong phương pháp chính của hoạt động của bạn, bạn nên kiểm tra isCancelled và xử lý trạng thái đó khi bạn thực sự bị hủy.

Để biết thêm thông tin, hãy xem Creating and Managing Operation Objects trong Hướng dẫn lập trình luồng.

+0

Nhưng hãy xem các câu trả lời khác, có vẻ như bạn không thể làm điều này (ít nhất là theo cách tiêu chuẩn kiểm tra 'isCancelled') khi sử dụng' NSInvocationOperation'. – jrdioko

5

Bài đăng ở trên rất tuyệt, nhưng để trực tiếp trả lời câu hỏi gốc: có vẻ như bạn không thể dừng đối tượng NSInvocationOperation vì nó không hỗ trợ hủy. Bạn sẽ phải phân lớp nó.

11

CẬP NHẬT: Công cụ hiển thị rò rỉ khi làm việc này. Tiến hành thận trọng! Tôi đang giữ điều này ở đây trong trường hợp tôi thực sự đang làm gì đó và một người khác có thể tìm ra cách vượt qua rào cản rò rỉ.

Dưới đây là một ý tưởng xoắn, mà tôi lại cố gắng như tôi loại này:

Đặt hoạt động như đối tượng cho NSInvocationOperation 's initWithTarget: selector: đối tượng: phương pháp. Giả sử bạn đã có một NSOperationQueue (chúng tôi sẽ gọi nó là đợi):

NSInvocationOperation *operation = [NSInvocationOperation alloc]; 
operation = [operation initWithTarget:self selector:@selector(myOperation:) object:operation]; 
[queue addOperation:operation]; 
[operation release]; 

Lưu ý rằng chúng ta phải phá vỡ các alloc vào cuộc gọi riêng của mình. Nếu không, chúng tôi không thể đặt đối tượng thành hoạt động!

Sau đó, trong phương thức hoạt động của bạn, đưa đối tượng trở lại và rà soát séc cho isCancelled như mong muốn. Ví dụ:

- (void)myOperation:(id)object { 
    NSInvocationOperation *operation = (NSInvocationOperation *)object; 
    if ([operation isCancelled]) return; 
    ... 
    } 

Hãy chắc chắn chọn của bạn kết thúc với một dấu hai chấm trở lại trong initWithTarget: ... cuộc gọi, vì bạn sẽ được thông qua trong một đối tượng bây giờ.

Cho đến nay, rất tốt. Bây giờ nếu tôi có thể buộc cancelAllOperations, tôi sẽ biết nếu điều này thực sự hoạt động. :)

+0

Sẽ không thử vì rò rỉ. Nhưng ý tưởng là tuyệt vời! –

8

Bạn cần kiểm tra xem NSInvocationOperation isCancelled is YES. Để làm điều đó trong NSInvocationOperation, bạn có thể sử dụng chính trị quan trắc:

Thêm đối tượng của bạn như NSInvocationOperation isCancelled quan sát khi chạy các hoạt động:

NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:<targetObj> selector:@selector(<targetMethod>) object:nil]; 
[operation addObserver:<targetObj> forKeyPath:@"isCancelled" options:NSKeyValueObservingOptionNew context:nil]; 
[operQueue addOperation:operation]; 
[operation release]; 

Sau đó, trong targetObj thực hiện

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context; 

để xem cho isCancelled bị thay đổi bởi cancelOOperations của NSOperationQueue. Bạn có thể đặt cờ riêng ở đây và targetMethod có thể kiểm tra và hủy nếu cần.

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