15

Tôi đang chuyển mã của mình từ GCD thông thường sang NSOperationQueue vì tôi cần một số chức năng. Rất nhiều mã của tôi dựa trên dispatch_after để hoạt động đúng. Có cách nào để làm điều gì đó tương tự với NSOperation không?dispatch_after tương đương trong NSOperationQueue

Đây là một số mã của tôi cần được chuyển đổi thành NSOperation. Nếu bạn có thể cung cấp một ví dụ về chuyển đổi nó bằng cách sử dụng mã này, đó sẽ là tuyệt vời.

dispatch_queue_t queue = dispatch_queue_create("com.cue.MainFade", NULL); 
dispatch_time_t mainPopTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timeRun * NSEC_PER_SEC)); 
dispatch_after(mainPopTime, queue, ^(void){ 
    if(dFade !=nil){ 
     double incriment = ([dFade volume]/[self fadeOut])/10; //incriment per .1 seconds. 
     [self doDelayFadeOut:incriment with:dFade on:dispatch_queue_create("com.cue.MainFade", 0)]; 
    } 

}); 

Trả lời

22

NSOperationQueue không có bất kỳ cơ chế thời gian trong đó. Nếu bạn cần thiết lập độ trễ như thế này và sau đó thực hiện một thao tác, bạn sẽ muốn lập lịch NSOperation từ dispatch_after để xử lý cả độ trễ và tạo mã cuối cùng là NSOperation.

NSOperation được thiết kế để xử lý nhiều hoạt động hàng loạt. Trường hợp sử dụng hơi khác so với GCD, và trên thực tế sử dụng GCD trên nền tảng với GCD.

Nếu sự cố bạn đang cố giải quyết là nhận thông báo hẹn giờ có thể hủy, tôi khuyên bạn nên sử dụng NSTimer và vô hiệu hóa nó nếu bạn cần hủy. Sau đó, để đáp ứng với bộ đếm thời gian, bạn có thể thực thi mã của bạn hoặc sử dụng hàng đợi công văn hoặc NSOperationQueue.

3

Bạn có thể tiếp tục sử dụng dispatch_after() với một hàng đợi toàn cầu, sau đó sắp xếp các hoạt động trên hàng đợi hoạt động của bạn. Các khối được chuyển đến dispatch_after() không thực thi sau thời gian được chỉ định, chúng được lập lịch đơn giản sau thời gian đó.

Cái gì như:

dispatch_after 
(
    mainPopTime, 
    dispatch_get_main_queue(), 
    ^{ 
     [myOperationQueue addOperation:theOperationObject]; 
    } 
); 
1

Bạn có thể tạo NSOperation thực hiện chế độ ngủ: MYDelayOperation. Sau đó, thêm nó như là một phụ thuộc cho hoạt động công việc thực sự của bạn.

@interface MYDelayOperation : NSOperation 
... 
- (void)main 
{ 
    [NSThread sleepForTimeInterval:delay]; // delay is passed in constructor 
} 

Cách sử dụng:

NSOperation *theOperationObject = ... 
MYDelayOperation *delayOp = [[MYDelayOperation alloc] initWithDelay:5]; 
[theOperationObject addDependency:delayOp]; 
[myOperationQueue addOperations:@[ delayOp, theOperationObject] waitUntilFinished:NO]; 
+1

Điều này sẽ giữ cho các hoạt động tích cực trong hàng đợi, và trong trường hợp của một hàng đợi với một số giới hạn các hoạt động tích cực, giấc ngủ mà sẽ tổ chức các hoạt động hợp pháp khác từ thực thi. – Bogdan

+2

Đồng ý với @Bogdan. Đây không phải là một cách tiếp cận tốt. Bạn không bao giờ nên chặn các luồng hàng đợi hoạt động. – Randy

0
[operationQueue performSelector:@selector(addOperation:) 
        withObject:operation 
        afterDelay:delay];