iPhone - a delay between operations in the queue

后端 未结 4 1852
挽巷
挽巷 2021-02-03 15:20

I am adding operations to the queue using something like this

NSInvocationOperation *operation0 = [[NSInvocationOperation alloc] 
initWithTarget:self
selector:@s         


        
相关标签:
4条回答
  • 2021-02-03 15:24

    you can do like following manner

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

    and now add [NSThread sleepforTimeInterval:5] to at the end of each task

    0 讨论(0)
  • 2021-02-03 15:25

    Without extra code, you can't really guarantee that your NSOperations will run in serial - if Apple release a multiprocessor iOS device, it will run multiple operations in parallel. So firstly, you should set up the dependency chain between your operations. I would suggest that you achieve this using NSOperation's - (void)addDependency:(NSOperation *)operation. You could also roll your own fancy locking code...

    You can then add a sleep(5) to the end of each of your doStuff methods. If you need the sleep outside the doStuff methods, create a sleep NSOperation:

    - (void)sleepOperationBody; {
    sleep(0.5f);
    }
    
    NSInvocationOperation *operation1 = [[NSInvocationOperation alloc] 
    initWithTarget:self
    selector:@selector(sleepOperationBody) 
    object:nil];
    

    That said, without knowing in more detail what you need to happen, I think you perhaps just need one NSOperation that combines all three tasks and puts a sleep between them. That would certainly be simpler code.

    0 讨论(0)
  • 2021-02-03 15:41

    I have two ways to do such thing.

    First: Let the current thread to sleep on the tail of doStuff1, doStuff2, and doStuff3.

    Second: Sub-class NSOperation and override the method -(void)main. You can init a custom NSOperation with parameters of target and action like following:

    -(id)initWithTarget:(id)target action:(SEL)action;
    

    And execute this action of target in the -(void)main by

    [target performSelector:action];
    [NSThread sleepForTimeInterval:0.05];
    
    0 讨论(0)
  • 2021-02-03 15:43

    Using sleep is a big waste of a thread. This is bad in the Ghostbusters' sense.

    If you need a queue that executes its operations non-concurrently i.e. sequentially you can simpy set its maxConcurrentOperationCount variable to 1.

    queue.maxConcurrentOperationCount = 1;
    

    To pause between operations you could do two different things:

    a) Delay the queueing of each operation:

    //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); 
            });
    

    This will queue all operations without blocking.

    b) Every operation has to implement

    - (BOOL)isFinished
    

    as you probably already know.

    If your operation is "done" just delay setting its "done" variable by your desired delay. Use something like:

    // 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"];
        });
    

    Variant a) guarantees a pause between starting times of operations. Variant b) guarantees a pause between the end of an operation and the start of a next operation.

    0 讨论(0)
提交回复
热议问题