How to pause a for loop in objective C, Spritekit - objective-c

I was just wondering, if there was any way of pausing a for loop.
For instance,
for (i = 0; i<10 ; i++) {
NSLog(i);
//Pause should go here
}
The outcome should be:
1
(wait 1 sec)
2
(wait 1 sec)
etc.
Firstly, I thought that you could add SKAction *wait = [SKAction waitForDuration:1 completion:^{
, but then I wasn't sure if you could resume the loop from inside the completion brackets.
I have looked around and found NSTimer, but I am not sure how you could implement this, because I would have to call the loop after each interval and it i would never be more than 0.
Is there any way that you could pause the loop for an amount of time, then have it resume enumerating?

As a matter of style you'd normally reformat the loop to be tail recursive. So, instead of:
for(i = 0; i < 10; i++) {
// ... work here ...
}
You'd reformulate as:
void doWorkForIteration(int i, int limit) {
if(i == limit) return;
// ... work here ...
doWorkForIteration(i+1, limit);
}
...
doWorkForIteration(0, 10);
It recurses because it call itself. It is tail recursive because its recursive call is the very last thing it does.
Once you've done that, you can switch from a direct recursive call to a delayed one. E.g. with GCD:
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^{
doWorkForIteration(i+1, limit);
});
... or use [self performSelector: withObject: afterDelay:] or any of the other deferred call approaches.
To do literally what you want, you could use C's sleep call. But that thread will block for the number of seconds specified. So don't do it on the main thread unless you want your application to lock up.

Related

How to Print Natural Numbers Sequentially but in 2 different threads Objective-C

I'm new to working with concurrency in Objective-C. I've taken look at some demo codes of concurrency programming.
I want to print natural numbers sequentially but in 2 different threads. Like:
1: Thread-XX
2: Thread-YY
3: Thread-XX
4: Thread-YY
5: Thread-XX
6: Thread-YY
.....................
.....................
and so on. But I can't figure out how to do that. Any help?
We can show you how to do this, but it's not a very useful scenario. You're going to spent a lot of time coordinating these two threads with semaphores or the like, largely diminishing the value of having stuff running on multiple threads. Often when you write multithreaded code, you want to maximize concurrency by minimizing the amount of time spent waiting for some signal from some other thread. This attempt to alternate between these two threads is antithetical to our general intent of multithreaded programming.
That having been said, it could look a bit like:
dispatch_queue_t xx = dispatch_queue_create("xx", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t yy = dispatch_queue_create("yy", DISPATCH_QUEUE_SERIAL);
dispatch_semaphore_t semaphoreXX = dispatch_semaphore_create(0);
dispatch_semaphore_t semaphoreYY = dispatch_semaphore_create(1); // seed this with one extra signal from YY
NSInteger __block value = 0;
dispatch_async(xx, ^{
for (NSInteger i = 0; i < 100; i++) {
dispatch_semaphore_wait(semaphoreYY, DISPATCH_TIME_FOREVER); // wait for signal from YY
value += 1;
NSLog(#"%ld: xx", (long)value);
[NSThread sleepForTimeInterval:0.1]; // 1/10 second delay so we can see what's going on
dispatch_semaphore_signal(semaphoreXX); // send signal from XX
}
});
dispatch_async(yy, ^{
for (NSInteger i = 0; i < 100; i++) {
dispatch_semaphore_wait(semaphoreXX, DISPATCH_TIME_FOREVER); // wait for signal from XX
value += 1;
NSLog(#"%ld: yy", (long)value);
[NSThread sleepForTimeInterval:0.5]; // 1/2 second delay so we can see what's going on
dispatch_semaphore_signal(semaphoreYY); // send signal from YY
}
});
Usually when we're updating one variable from multiple threads, we'd synchronize our access to that object, but this "have the threads alternate" logic eliminates our need to do that, in this particular case.

Objective-C block doesn't skips code and then later executes it

I'm using the GPUImage framework and I've noticed that the compiler automatically skips everything that is within the brackets of the setColorAverageProcessingFinishedBlock. It completely skips over these contents and continues on, executing everything else in the code. Once everything else has been executed, it comes back to the content within the brackets. Obviously, this has unintended side effects.
NSMutableArray *redValues = [NSMutableArray array];
NSMutableArray *arrayOne = [NSMutableArray array];
NSUInteger arrayOneLength = [arrayOne count];
__block int counter = 0;
int amount = 1;
float totalOne, diffForAverage;
NSInteger j;
GPUImageVideoCamera *videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset640x480 cameraPosition:AVCaptureDevicePositionBack];
videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;
GPUImageAverageColor *averageColor = [[GPUImageAverageColor alloc] init];
[averageColor setColorAverageProcessingFinishedBlock:^(CGFloat redComponent, CGFloat greenComponent, CGFloat blueComponent, CGFloat alphaComponent, CMTime frameTime)
{ // the compiler runs until here, then skips everything within these brackets
NSLog(#"%f", redComponent);
[redValues addObject:#(redComponent * 255)];
}]; // after the brackets close, it executes everything that is below this
// once everything below this has been executed, it goes back to the brackets and executes
// everything between them
[videoCamera addTarget:averageColor];
[videoCamera startCameraCapture];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 27 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[videoCamera stopCameraCapture];
});
totalOne = [redValues[24] floatValue];
float average = totalOne / amount;
NSUInteger redValuesLength = [redValues count];
for (j = (counter + 24); j < (redValuesLength - 24); j++)
{
diffForAverage = average - [redValues[j + 1] floatValue];
if (diffForAverage > -1 && diffForAverage < 1)
{
totalOne += [redValues[j + 1] floatValue];
amount++;
[arrayOne addObject:[NSNumber numberWithInt:(j - 24)]];
counter++;
}
}
How can I solve this problem?
There are two issues with the above code: a memory management one, and a misunderstanding of how blocks work.
First, you're creating a GPUImageVideoCamera instance within a method, but not retaining it as an instance variable. I'm going to assume this is code using automatic reference counting, and if that's true, this camera instance will be deallocated the instant your method is finished. At best, you'll capture maybe one frame from the camera before this is deallocated. At worst, this will crash as the camera and the entire filter chain attached to it are deallocated mid-operation.
Make an instance variable on your containing class and assign your GPUImageVideoCamera instance to it to have it last long enough to be useful.
The second issue with the above is a misunderstanding about how and when blocks will execute. Blocks are merely sections of code you can pass around, and they don't necessarily execute in serial with the rest of the code around them.
In this case, the block you're providing is a callback that will be triggered after every frame of video is processed through the average color operation. This processing takes place asynchronously on a background queue, and you have to design your code to acknowledge this.
If you want X values to be built up, have each measurement be added to an array inside that block, and then within the block check for X values to be reached. At that point, average and do whatever with them. Basically, add a check within the block and move the code you have after it into the block to be run whenever the count is greater than X. You may wish to stop camera capture at that point, if that's all you need.
The code you post is working exactly as it is supposed to work. The color average processing takes a while so it is done on a background thread so the main thread isn't stalled. After the processing is done, then the block is called.
Any code that shouldn't be executed until after the processing is done needs to go inside the block.

Changing text field repeatedly in a loop only displays one final value [duplicate]

This question already has answers here:
NSTextField waits until the end of a loop to update
(4 answers)
Closed 9 years ago.
I wish to create a loop that increments an integer every ten seconds, and does this one hundred times. But when I use this code:
- (IBAction)loopTest:(id)sender {
}
- (IBAction)beginLoop:(id)sender {
for (i=0;i<100 ;i++ ) {
testingLoops++;
NSString *feed = [NSString stringWithFormat: #"%d", testingLoops];
self.feedLabel.stringValue = feed;
[NSTimer scheduledTimerWithTimeInterval:10 target:self selector:#selector(loopTest:) userInfo:nil repeats:NO];
}
}
the application just displays the integer as 100 straight away. I have it so that it runs the beginLoop when I press a button. What's going on?
Your statement:
[NSTimer scheduledTimerWithTimeInterval:10
target:self
selector:#selector(loopTest:)
userInfo:nil
repeats:NO];
does not delay your loop - rather for every iteration of the loop it schedules a timer to call loopTest:, a method you've defined to do nothing.
To use a timer to delay a loop you need to schedule a method which performs the remainder of the loop. In other words a non-loop method which performs the equivalent of one iteration of your loop and then schedules a time to perform the remainder.
Following your approach, but switching to use an implicit timer provided by performSelector:withObject:afterDelay as it is more convenient here, this gives us:
- (IBAction)beginLoop:(id)sender
{
// start "loop"
// note we only pass the current index and not the limit or delay
// as there is no performSelector version which directly supports
// passing three values to the selector
[self doLoopIndex:#0];
}
- (void) doLoopIndex:(NSNumber *)objIndex
{
// extract int from NSNumber - we use the later as the argument type so we can use performSelector below
int index = objIndex.intValue;
// do the work of one iteration
NSString *feed = [NSString stringWithFormat: #"%d", index];
self.feedLabel.stringValue = feed;
// increment "loop" counter and schedule next iteration if needed
// note the use of #(index) to create an NSNumber as an object is required
index++;
if (index < 100)
[self performSelector:#selector(doLoopIndex:) withObject:#(index) afterDelay:1];
}
This is not the only way to achieve your goal. Using blocks and "Grand Central Dispatch" (GCD) is another and in this case has the advantage that passing three values: current index, limit and delay; is easier.
For example, a general loop with delay might be written as:
- (void) doLoop:(int)index // starting index
limit:(int)limit // limit
delay:(NSTimeInterval)delayInSeconds // delay each iteration
body:(void (^)(int))body // block for loop body
{
// invoke the body block
body(index);
// increment index and schedule next "iteration" if needed
index++;
if (index < 100)
{
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void)
{
[self doLoop:index limit:limit delay:delayInSeconds body:body];
});
}
}
See the documentation for the details of the dispatch_X methods and types.
This might look more complicated, but that is because it is more general. Using the above your particular loop becomes just:
- (IBAction)beginLoop:(id)sender
{
[self doLoop:0 limit:100 delay:1 body:^(int index)
{
NSString *feed = [NSString stringWithFormat: #"%d", index];
self.feedLabel.stringValue = feed;
}];
}
Which of the above approaches, or using an explicit timer as your original code did, is appropriate for your use case is your choice - there is no single "right" answer.
HTH.
Try this
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, i * NSEC_PER_SEC),
dispatch_get_main_queue(), ^{
yourtextfield.text=[NSString stringWithFormat:#"%d", i];
});

Objective c - Run block of code for X seconds but return immediately if condition satisfies

So the situation is I need to run the code for 5 seconds but if I match the condition then want it to immediately return back. I am doing this in KIF test steps and I don't want this to block my applications main thread.
Sample pseudo Code -
+ (BOOL) isVerified:(NSString*)label;
{
if(<condition match>)
return YES;
else if(X seconds not passed)
<make sure m running this function for X seconds>
else // X seconds passed now..
return NO;
}
If you don't want to block the main thread in the case that NO should be returned after 5 sec delay, then structure that API asynchronously.
typedef void(^CCFVerificationCallbackBlock)(BOOL verified);
#interface CCFVerifier : NSObject
- (void)verifyLabel:(NSString *)label withCallbackBlock:(CCFVerificationCallbackBlock)block;
#end
static const int64_t ReturnDelay = 5.0 * NSEC_PER_SEC;
#implementation CCFVerifier
- (void)verifyLabel:(NSString *)label withCallbackBlock:(CCFVerificationCallbackBlock)block {
NSParameterAssert(block);
if( [label isEqualToString:#"moo"] )
block(YES);
else {
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, ReturnDelay);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
block(NO);
});
}
}
#end
To use:
_verifier = [[CCFVerifier alloc] init];
[_verifier verifyLabel:#"foo" withCallbackBlock:^(BOOL verified) {
NSLog(#"verification result: %d",verified);
}];
Don't block or poll.
set a timer for 5 seconds
if whatever condition is met, check the condition after 5 seconds and do the fail case or success case if necessary
if you want to take action immediately on completion, then use any of the various "perform thing on main thread" constructs to do so (also setting the condition to let the timer firing no that the task was done)
you can invalidate the timer to keep it from firing at all, if you want.

GCD Poor Performance

As you may remember, I am trying to use GCD to speed up some of my code, namely a collision detection and resolution engine. However, I am clearly doing something wrong because all of my GCD code is significantly slower and less consistent than my serial code (between 1.4x and 10x slower). Allow me to give you an example: I am iterating over an array in a bubble-sort fashion to determine all possible collisions among objects in that array:
- (double) detectCollisionsInArray:(NSArray*)objects
{
int count = [objects count];
if (count > 0)
{
double time = CFAbsoluteTimeGetCurrent();
for (int i = 0; i < count; i++)
{
for (int j = i + 1; j < count; j++)
{
/** LOTS AND LOTS OF WORK FOR EACH OBJECT **/
}
}
return CFAbsoluteTimeGetCurrent() - time;
}
return 0;
}
Pretty straightforward, and it seems to perform well given the constraints of the problem. However, I would like to take advantage of the fact that the state of each object is not modified in the code section and use GCD to parallelize this work. To do this I am trying something like this:
- (double) detectCollisionsInArray:(NSArray*)objects
{
int count = [objects count];
if (count > 0)
{
NSOperationQueue* opQueue = [[NSOperationQueue alloc] init];
NSBlockOperation* blockOperation = nil;
double time = CFAbsoluteTimeGetCurrent();
for (int i = 0; i < count; i++)
{
for (int j = i + 1; j < count; j++)
{
void (^workBlock) (void) = ^()
{
/** LOTS AND LOTS OF WORK FOR EACH OBJECT **/
};
if (!blockOperation)
{
blockOperation = [NSBlockOperation blockOperationWithBlock:b];
}
else
{
[blockOperation addExecutionBlock:workBlock];
}
}
}
[opQueue addOperation:blockOperation];
[opQueue autorelease];
return CFAbsoluteTimeGetCurrent() - time;
}
return 0;
}
Can anyone help to put me on the right track and perhaps provide a link to a good GCD tutorial? I have looked over several GCD tutorials and scoured all of the documentation and I still feel that my grasp on the subject is tenuous at best. Thanks!
Is there a reason you're not using the GCD C API and the dispatch_* family of functions? You don't have much control over the GCD aspects of NSOperationQueue (like which queue you want to submit the blocks to). Also, I can't tell if you're using iOS or not, but NSOperationQueue does not use GCD on iOS. That might be the reason it spawned so many threads. Either way, your code will be shorter and simpler if you use the GCD API directly:
- (double) detectCollisionsInArray:(NSArray*)objects
{
int count = [objects count];
if (count > 0)
{
double time = CFAbsoluteTimeGetCurrent();
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
for (int i = 0; i < count; i++)
{
dispatch_group_async(group, queue, ^{
for (int j = i + 1; j < count; j++)
{
dispatch_group_async(group, queue, ^{
/** LOTS AND LOTS OF WORK FOR EACH OBJECT **/
});
}
});
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
dispatch_release(group);
return CFAbsoluteTimeGetCurrent() - time;
}
return 0;
}
You can use a dispatch_group to group all of the executions together and wait for them all to finish with dispatch_group_wait. If you don't care to know when the the blocks finish, you can ignore the group part and just use dispatch_async. The dispatch_get_global_queue function will get one of the 3 concurrent queues (low, default or high priority) for you to submit your blocks to. You shouldn't have to worry about limiting the thread count or anything like that. The GCD scheduler is supposed to do all of that for you. Just make sure you submit to a concurrent queue, which could either be one of the 3 global queues, or a queue you've created by passing DISPATCH_QUEUE_CONCURRENT to dispatch_queue_create (this is available starting OS X 10.7 and iOS 5.0).
If you're doing some file I/O in each block or taxing some other resource, you might need to reign in GCD and limit the number of blocks you're submitting to the queue at once. This will have the same effect as limiting the concurrent operation count in an NSOperationQueue. You can use a GCD semaphore to do this:
- (double) detectCollisionsInArray:(NSArray*)objects
{
int count = [objects count];
if (count > 0)
{
double time = CFAbsoluteTimeGetCurrent();
dispatch_group_t group = dispatch_group_create();
dispatch_semaphore_t semaphore = dispatch_semaphore_create(10);
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
for (int i = 0; i < count; i++)
{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_group_async(group, queue, ^{
for (int j = i + 1; j < count; j++)
{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_group_async(group, queue, ^{
/** LOTS AND LOTS OF WORK FOR EACH OBJECT **/
dispatch_semaphore_signal(semaphore);
});
}
dispatch_semaphore_signal(semaphore);
});
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
dispatch_release(group);
dispatch_release(semaphore);
return CFAbsoluteTimeGetCurrent() - time;
}
return 0;
}
Once you get the hang of it, GCD is very simple to use. I use it all over my code now.
Can anyone help to put me on the right track and perhaps provide a link to a good GCD tutorial?
Run, don't walk over to Mike Ash's blog. His series on GCD is the clearest and most concise I've seen, and it'll only take you around 30 minutes to read the whole thing. Apple's WWDC videos from 2010 on GCD And blocks are also pretty good.
In your code you are delaying the work you need to do for each object until the end of the nested for loop. That said, when the loop finishes you will have one operation with lots of blocks for a bunch of objects and you won't thereby take advantage of the GCD properly.
I would suggest you create one NSBlockOperation for each object and add it to the NSOperationQueue in the end of each for (int j = i + 1; j < count; j++) iteration.
This way, the system will begin processing the work you need to do for each object as soon as the iteration ends.
Also keep in mind that the queue shouldn't be much larger than the available processors, otherwise you will have some overhead on the thread switch process that will compromise speed.