2009-10-03 32 views
6

Tôi đang làm việc với một số mã thực hiện một loạt các hoạt động không đồng bộ với các cuộc gọi lại khác nhau; Snow Leopard đã làm điều này cực kỳ dễ dàng với các khối và GCD.Làm thế nào nhẹ là NSOperationQueue trên Snow Leopard?

Tôi gọi NSTask từ một NSBlockOperation như vậy:

[self.queue addOperationWithBlock:^{ 
    NSTask *task = [NSTask new]; 
    NSPipe *newPipe = [NSPipe new]; 
    NSFileHandle *readHandle = [newPipe fileHandleForReading]; 
    NSData *inData = nil; 
    [task setLaunchPath:path]; 
    [task setArguments:arguments]; 
    [task launch]; 

    while ((inData = [readHandle availableData]) && [inData length]) { 
     [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 
      // callback 
     }]; 
    } 

    [task waitUntilExit]; 
}]; 

Cách tiếp cận này hoạt động hoàn hảo. Nó giống như ma thuật, miễn là callbacks của tôi xử lý đồng thời một cách chính xác.

Bây giờ, tôi muốn có thể kết hợp một số cuộc gọi này; đây là phương thức "refresh" của đối tượng mô hình và có thể mất nhiều thời gian để hoàn thành. Có bảng xếp hạng người dùng trên nút làm mới không nên buộc máy và tất cả những thứ đó.

Tôi có thể thấy tình trạng khó xử thực hiện tại đây. Tôi có thể tạo toàn bộ hàng đợi - một cho mỗi loại cuộc gọi - và đặt số lượng hoạt động đồng thời của họ thành 1 và sau đó gọi -cancelAllOperations bất cứ khi nào đến lúc có cuộc gọi mới. Cách khác, tôi có thể thực hiện một số sổ sách kế toán thủ công hơn mà các cuộc gọi hiện đang diễn ra và quản lý một hàng đợi cho mỗi đối tượng mô hình (như tôi đang làm) hoặc tôi có thể tiến xa hơn và sử dụng hàng đợi toàn cầu.

Mức độ nặng là NSOperationQueue? Đang tạo ra nhiều hàng đợi một quyết định kiến ​​trúc xấu? Có cách nào tốt hơn để kết hợp các nhiệm vụ này không?

+2

FYI, bạn đang làm rò rỉ NSTask và NSPipe của bạn. + mới tương đương với + alloc/-init, có nghĩa là bạn chịu trách nhiệm giải phóng chúng ... mà bạn không bao giờ làm (trong mã của bạn ở trên). (trừ khi, tất nhiên, bạn đang sử dụng GC) –

+1

Đó là một chương trình chỉ dành cho Snow Leopard. Tôi chắc chắn hy vọng mã vạch chỉ có nhãn hiệu Snow-Leopard mới của bạn được thu gom rác. :-D –

Trả lời

8

Nếu bạn lo ngại về hiệu suất, đừng đoán: đo lường và sau đó sửa bất kỳ tắc nghẽn nào bạn tìm thấy. Thêm hàng đợi là đơn giản; thử nó và xem những gì cụ nói với bạn về hiệu ứng trên hiệu suất.

Lý do chính để tạo nhiều hàng đợi là trong trường hợp bạn có lý do nào đó để bắt đầu và dừng chúng. Nếu bạn chỉ muốn có được những lợi ích của libdispatch, bạn có thể nhận được điều đó bằng cách thêm các hoạt động vào hàng đợi chính.

0

Chỉ cần sử dụng nhiều hàng đợi hoạt động như bạn muốn. Họ đang ở đây để tách các phần logic của chương trình của bạn. Tôi không nghĩ bạn nên quá lo lắng về hiệu suất miễn là bạn không phân bổ hàng trăm hàng đợi mỗi giây.

+0

Trang web? Điều này phải làm gì với các trang web? –

+0

Cảm ơn, vẫn còn quá sớm vào buổi sáng. :) –

1

Bạn có thể thêm nhiều khối vào NSBlockOperation sẽ được thực hiện đồng thời và có thể bị hủy bởi hủy thao tác có chứa. Miễn là các tác vụ cá nhân của bạn không cần phải được tuần tự hóa, điều này có thể hoạt động.

+0

Đó không phải là những gì các tài liệu nói: "Lớp NSBlockOperation là một lớp con cụ thể của NSOperation quản lý việc thực thi đồng thời một hoặc nhiều khối." http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Reference/NSBlockOperation_class/Reference/Reference.html –

+0

Jim, bạn hoàn toàn chính xác. Đã cập nhật câu trả lời. Cảm ơn. –

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