Using NSThread Mode in NSOperation

When working with some code, I come across cycle loops for which I am new to inside NSOperation s.

NSOperation are busy loading data - and while they are busy, there is code waiting for the download to complete, in the form of NSRunLoop and a sleeping stream.

This code, in particular, interests me:

 while (aCertainConditionIsTrue && [self isCancelled]==NO) { if(![[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:1.0]]){ [NSThread sleepForTimeInterval:1.0]; } } 

I read about startup loops, and runMode:beforeDate: will wait for an input source or timeout. Although I am not 100% what is considered input juice.

The first time this is done, it always returns NO and calls sleepForTimeInterval: This is bad?

In a particular utility class, it strikes sleepForTimeInterval: many times - once for each thread, which significantly degrades performance.

Any better solutions or tips?

+6
source share
2 answers

Sleep mode blocks the flow. You may have changed your code to use performSelector: withObject: afterDelay. This way your thread can continue to work.

  ... done = NO; [self checkDoneCondition:nil]; ... - (void)checkDoneCondition:(id)object { if (aCertainConditionIsTrue && [self isCancelled]==NO) { if(...) { [self performSelector:@selector(checkDoneCondition:) withObject:[con error] afterDelay:1.0]; } else { done = YES; } } } 
+2
source

It looks like you need to use concurrent NSOperation. Here is the relevant part in the Apple docs:

Unlike a noncompetitive operation that runs synchronously, simultaneous work runs asynchronously. In other words, when you call the start method of a parallel operation, this method can do the corresponding task before. This can happen because the operation object created a new thread to perform the task or because the operation is called an asynchronous function. It doesnโ€™t really matter if the operation continues when control returns to the caller, only that it can continue. (...) In a parallel operation, your start method is responsible for starting the operation asynchronously. If you create a thread or call an asynchronous function, you do this from this method. After the operation starts, your startup method should also update the operation status reported by the isExecuting method. You do this by sending KVO notifications to the isExecuting key path, which lets interested customers know that the operation is now in progress. Your isExecuting method should also return status in thread safe mode.

(from https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/NSOperation_class/Reference/Reference.html )

In other words, you can override the -start method in a subclass of NSOperation and have ivar for the executing and finished properties. This method will start loading in a separate thread. When the download starts, you set the executing flag and start KVO. If it is completed in this thread, you do the same with finished and executing . It seems complicated, but actually it's pretty simple.

See also this stack overflow question with a great explanation: NSOperation subclassing will be simultaneous and cancellation

+1
source

Source: https://habr.com/ru/post/906403/


All Articles