如何使用带有调度gcd的NSOperationQueue和NSBlockOperation? [英] How to work with NSOperationQueue and NSBlockOperation with dispatch gcd?

查看:171
本文介绍了如何使用带有调度gcd的NSOperationQueue和NSBlockOperation?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里是代码

@interface ViewController ()
@property (nonatomic, strong) NSOperationQueue *queue;
@end


@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];

    _queue = [[NSOperationQueue alloc] init];

    NSBlockOperation *aBlockOperation = [[NSBlockOperation alloc] init];
    __weak NSBlockOperation* aWeakBlockOperation = aBlockOperation;

    [aBlockOperation addExecutionBlock:^{
        NSLog(@"queue should still have the operation. And it does. yay!: %@", [_queue operations]); // This should print correctly. It will show the NSBlock operation correctly residing inside the NSOperationQueue
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            NSLog(@"Now queue is empty??: %@", [_queue operations]); // This should print as being empty
            NSLog(@"And a weak block is nil???: %@", aWeakBlockOperation); // This should print out **nil**
            if (![aWeakBlockOperation isCancelled]) {
                // Now i have no way to check the operation
            }

        });
    }];

    [_queue addOperation:aBlockOperation];
@end

[编辑]
目标是要有这样的用户交互:
屏幕上有一个tableView包含5个或更多单元格。用户单击单元格时,后台进程将执行需要一段时间的后台进程。该应用程序将每隔3秒检查一次用户是否单击了另一个单元格。如果用户单击了另一个单元格,则应从队列中取消当前操作,并开始处理用户单击的新单元格。

[Edit] The goal is to have a user interaction like this: There is a tableView on screen with 5 or more cells. When ever a user click a cell, background process will perform background process that will take a while. The App will, at 3 second intervals, check to see if the user clicked on another cell. If the user clicked on another cell, I should cancel the current operation from queue, and begin processing the new one the user clicked on.

从上面的代码中我有2个我无法解决的问题。

From the code above i have 2 problems i cant solve.


  1. 我如何做到这一点,以便弱引用不会在dispatch_after块中释放?将其放置在此处的目的是将应用暂停3秒钟。如果dispatch_after不正确,那么我在那使用什么代码防止它变为nil?

  1. How do i make it so that my weak reference isnt deallocated in the dispatch_after block? The goal of putting it there is to pause the app for exactly 3 seconds. If dispatch_after is incorrect, then what code do i use there to prevent it becoming nil?

为什么在我调用dispatch_after之后我的NSOperationQueue变成空?有没有办法使它不为空?

Why is it that my NSOperationQueue become empty after I call dispatch_after? Is there a way to make it not become empty?


推荐答案

dispatch_after 计划该块并立即返回。因此,您的 NSBlockOperation 的executionBlock几乎无事可做-它立即完成并从队列中删除。那时,该操作被释放,因此弱引用在以后调用 dispatch_after 块之前变为零。

dispatch_after schedules the block and returns immediately. So, your NSBlockOperation's executionBlock has almost no work to do — it immediately finishes and is removed from the queue. At that time, the operation is released and so the weak reference becomes nil before the dispatch_after block is called later.

如果首先执行 dispatch_after 并从该块内部计划操作,则可能会满足您的需求。您可以只使用 sleep ,但我不建议您这样做,因为您将不必要地阻塞线程。有关NSO操作和延迟的更多讨论,请参见此问题

If you do the dispatch_after first and schedule the operation from inside that block, it might suit your needs. You could just use sleep, but I wouldn't recommend that since you will be unnecessarily blocking a thread. See this question for more discussion on NSOperation and delays.

这篇关于如何使用带有调度gcd的NSOperationQueue和NSBlockOperation?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆