Reputation: 1885
i have a problem with queued functions. i want to run my function and when my first function finishes running, i want to start other one.
-(void)firstFunct
{
// sending and getting information from server.
// doing sth and creating data to use in my second function.
}
and my second function is:
-(void)secondFunct
{
// using data coming from first function
}
i am now using these 2 functions in like that
-(void)ThirdFunct
{
[self firstFunct];
[self performSelector:@selector(secondFunct) withObject:nil afterDelay:0.5];
}
but there is a problem that this method is not good to use. i want to learn if there is an efficient way to run the functions one after the other.
Upvotes: 0
Views: 3651
Reputation: 141899
Cocoa offers nice concurrency management classes like NSOperation
and NSOperationQueue
. You could use them to simplify the logic behind chaining your asynchronous calls without creating explicit connections in code to call method 3 after work 2 completes, and method 2 after work 1 completes, and so on. Using dependency management, you could easily specify those dependencies between your operations.
Here's a simple example of how you would use that code. Suppose you are downloading some data asynchronously in all those three methods, and you've created a NSOperation
subclass called DownloadOperation
.
First, create a NSOperationQueue
.
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
Then, create the three download operations.
DownloadOperation *a = [[DownloadOperation alloc] init];
DownloadOperation *b = [[DownloadOperation alloc] init];
DownloadOperation *c = [[DownloadOperation alloc] init];
Then, specify the dependencies between your operations. Dependencies simply say that an operation can run only if all the operations it depends upon are complete. In your example, the dependencies look like c <- b <- a
, which can be broken down into two steps:
[b addDependency:a];
[c addDependency:b];
Now add these operations to the queue.
[queue addOperations:@[ a, b, c ] waitUntilFinished:NO];
The queue will automatically start processing all operations at this point, but since we've creating this chaining sort of a dependency, they will be executed one after the other in our particular example.
I've created a sample project on github demonstrating it with a simple example at https://github.com/AnuragMishra/ChainedOperationQueue. It fakes an asynchronous operation by creating a timer, and when the timer finishes, the operation is marked complete. It's written using Xcode 4.5, so let me know if you have issues compiling it in older versions.
Upvotes: 3
Reputation: 104698
Well, yes, zoul's spot on for the normal case.
However, you mentioned a server was involved. In that case, you probably have an asynchronous request. What you want to do is read the documentation of the class you use to make the network request, and learn what callbacks it uses to notify you when it is complete.
Upvotes: 4
Reputation: 5499
if you write your methode like this
-
(void)ThirdFunct
{
[self firstFunct];
[self secondFunct];
}
secondFunct
is called after firstFunct
. Your problem comes certainly from the network request which is asynchronous. To be sure that your secondFunct
is executed after an asynchronous request you have to execute it from delegate or block.
Checkout NSURLConnectionDelegate if you NSURLConnection
Upvotes: -2
Reputation: 104085
You can simply call one function after the other:
- (void) thirdFunct
{
[self firstFunct];
[self secondFunct];
}
If you want to run this whole block in the background, not blocking the UI thread, use Grand Central Dispatch:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_NORMAL, 0), ^{
[self firstFunct];
[self secondFunct];
});
And if the first function contains some asynchronous call, that call should offer some kind of interface to run code after the call finishes, like a delegate call or a completion block.
Upvotes: 4