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。 您可以使用参数target和action初始化自定义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"];
});