iPhone-队列中操作之间的延迟

iPhone-队列中操作之间的延迟,iphone,Iphone,我正在使用类似这样的方法向队列添加操作 NSInvocationOperation *operation0 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doStuff1) object:nil]; [queue addOperation:operation0]; [operation0 release]; NSInvocationOperation *operation1 = [[

我正在使用类似这样的方法向队列添加操作

NSInvocationOperation *operation0 = [[NSInvocationOperation alloc] 
initWithTarget:self
selector:@selector(doStuff1) 
object:nil];

[queue addOperation:operation0];
[operation0 release];   


NSInvocationOperation *operation1 = [[NSInvocationOperation alloc] 
initWithTarget:self
selector:@selector(doStuff2) 
object:nil];

[queue addOperation:operation1];
[operation1 release];   


NSInvocationOperation *operation2 = [[NSInvocationOperation alloc] 
initWithTarget:self
selector:@selector(doStuff3) 
object:nil];

[queue addOperation:operation2];
[operation2 release];   
队列设置为一次只执行一个操作。因此,它将毫不延迟地一个接一个地运行这三种方法。这是不是一种增加小延迟的方法,比如说在每次操作之间增加0.5秒或其他时间,这样就不用运行了

doStuff1
doStuff2
doStuff3
排队就可以了

doStuff1
sleep for X seconds
doStuff2
sleep for X seconds
doStuff3
?


谢谢。

我有两种方法做这件事

首先:让当前线程睡在doStuff1、doStuff2和doStuff3的尾部

第二:子类NSOperation并重写方法-(void)main。 您可以使用参数targetaction初始化自定义NSO操作,如下所示:

-(id)initWithTarget:(id)target action:(SEL)action;
并通过以下方式在-(void)main中执行目标的此操作:


如果没有额外的代码,你就不能保证你的操作会以串行方式运行——如果苹果发布一个多处理器的iOS设备,它会并行运行多个操作。因此,首先,您应该在操作之间建立依赖链。我建议您使用NSOperation的
-(void)addDependency:(NSOperation*)操作实现这一点。你也可以使用你自己的锁码

然后,您可以在每个doStuff方法的末尾添加一个sleep(5)。如果需要doStuff方法之外的睡眠,请创建睡眠操作:

- (void)sleepOperationBody; {
sleep(0.5f);
}

NSInvocationOperation *operation1 = [[NSInvocationOperation alloc] 
initWithTarget:self
selector:@selector(sleepOperationBody) 
object:nil];

也就是说,在不知道需要做什么的情况下,我认为您可能只需要一个NSO操作,将所有三个任务结合起来,并在它们之间放置一个睡眠。这肯定是更简单的代码。

您可以按照以下方式执行

[operation0 addDependancy:operation1];
[operation1 addDependancy:operation2];

现在在每个任务结束时添加[NSThread sleepforTimeInterval:5]

使用睡眠是对线程的极大浪费。从捉鬼者的角度来看,这是不好的

如果您需要一个非并发(即顺序)执行其操作的队列,可以简单地将其maxConcurrentOperationCount变量设置为1

queue.maxConcurrentOperationCount = 1;
要在操作之间暂停,可以执行两种不同的操作:

a) 延迟每个操作的排队:

//loop over the operations to be queued with and index
      double delayInSeconds = 2.0 * index;
        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
        dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
            queue.addOperation(operation at index); 
        });
这将在不阻塞的情况下对所有操作进行排队

b) 每项行动都必须执行

- (BOOL)isFinished
你可能已经知道了

如果您的操作是“完成”的,只需延迟设置其“完成”变量所需的延迟。使用类似于:

// Operation is done with its work, but we tell the Queue only after 2 seconds, so the queue will start the next operation later
double delayInSeconds = 2.0;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
 __weak __typeof(self)weakSelf = self;
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[weakSelf willChangeValueForKey:@"isExecuting"];
    [weakSelf willChangeValueForKey:@"isFinished"];
    weakSelf.executing = NO;
    weakSelf.finished  = YES;
    [weakSelf didChangeValueForKey:@"isFinished"];
    [weakSelf didChangeValueForKey:@"isExecuting"];
    });
变量a)保证在操作开始时间之间暂停。
变量b)保证在一个操作结束和下一个操作开始之间有一个暂停。

添加一个在其他操作之间有睡眠的操作怎么样?这是什么操作?这就是问题……:)创建一个NSInvocationOperation,就像您所做的那样,但是执行的方法会运行一个
sleep
。谢谢,但是您是否愿意在答案中转换您的注释并在其中放置一些代码,这样我就可以很高兴地将答案授予您?一般的答案没有帮助。。。我需要一些代码来查看。。。请…谢谢。你到底想做什么?我缺乏想象力去想一个必要的场景。也许有一种更好的方法可以在不破坏NSO操作的情况下获得相同的结果?就是这样。我将简化代码。这只是初稿。但是关于并发性,我认为命令“[queue setMaxConcurrentOperationCount:1];”足以限制并行执行的数量……谢谢。>如果没有额外的代码,您就无法真正保证NSO操作将以串行方式运行。嗯,是的,你可以,对吗?只需将NSOperationQueue上的maxConcurrentOperations设置为1。这样就可以了,不是吗?调用sleep()会导致操作队列中的所有内容都停止!!即使您有并发操作,如果它们都在同一个线程上运行,它们也可能会停止。因此,除非您在操作中创建自己的线程,否则您可能会遇到麻烦。这是我在实践中的经验。如果我做错了,请纠正我。选项b绝对是这里所有解决方案中最干净的,并且不涉及不必要的阻塞队列。对我来说很好,谢谢你!如果与其他解决方案相比,这感觉设置太多,那么我建议您考虑一些类似PSOperations()的东西,它为您封装了大部分KVO。这应该是正确的答案,使用睡眠会产生意外的后果,除非您创建了自己的线程。
// Operation is done with its work, but we tell the Queue only after 2 seconds, so the queue will start the next operation later
double delayInSeconds = 2.0;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
 __weak __typeof(self)weakSelf = self;
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[weakSelf willChangeValueForKey:@"isExecuting"];
    [weakSelf willChangeValueForKey:@"isFinished"];
    weakSelf.executing = NO;
    weakSelf.finished  = YES;
    [weakSelf didChangeValueForKey:@"isFinished"];
    [weakSelf didChangeValueForKey:@"isExecuting"];
    });