sequential methods execution obj-c - objective-c

Very beginner obj-c question.
My task is to do simple sequence when view loads:
pause 2 secons
method1 execution
pause 2 seconds
method2 execution
pause 2 seconds
method3 execution
I write this code for iOS5+ so blocks or other features can be used. I tried
[NSThread sleepForTimeInterval:x];
to make the pauses between methods executions, but three pauses added to one and I have one big pause, so it's wrong piece.
How to do this in right way?

Sleeping an NSThread is never the right way to handle timed method execution. You want NSTimer, which you can set to either fire the same method after two seconds (then have that method determine which selector to perform next), or have three timers set to fire two seconds after each other, each calling a different method.

You could use performSelector:withObject:afterDelay:, or as CodaFi said, an NSTimer. Either method allows to to pass an object to the method, and that object could be an array or dictionary, if you need to pass multiple arguments.

I'd chain the methods:
call 1. method and make it call 2.
method should call 3.
should proceed to 4.
...

Related

In Objective-c is performSelector executed inline or is it posted for execution as a different event?

There are plenty of reasons why this matters. Here's a simple example if you weren't using ARC.
[instance performSelector:selector withObject:objectA];
[objectA release]; // Did the selector actually finish executing
// in the line above so everyone's done with objectA
// or did the selector merely get scheduled in the line
// above, and is yet to execute, so objectA had better
// not be released yet?
I've done some research and context clues seem to point to selector getting done inline. But I haven't seen any definitive statement anywhere I've looked, that states it gets executed inline.
performSelector:withObject: is executed synchronously (block until the method finished).
Use performSelector:withObject:afterDelay: to execute method asynchronously on main thread (return immediately and execute later).
Use performSelectorInBackground:withObject: to execute method asynchronously on background thread (return immediately and execute on different thread).
Note:
performSelector and its friends should be avoid because it is undefined behaviour if you use them on method with incompatible method signature.
The aSelector argument should identify a method that takes no arguments. For methods that return anything other than an object, use NSInvocation.
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/index.html#//apple_ref/occ/intfm/NSObject/performSelector:
Did the selector actually finish executing in the line above so
everyone's done with objectA or did the selector merely get scheduled
in the line above, and is yet to execute, so objectA had better not be
released yet?
It doesn't matter, for memory management purposes. Memory management in Cocoa is local -- you only need to care what your function does; you don't need to know, and shouldn't care, what other functions do internally, to manage memory correctly (ignoring retain cycles). As long as you're done with your owning reference, you should release it. It doesn't matter to you if other people are done with it.
This is because, according to Cocoa memory management rules, any function which needs to store it for use beyond the function call is required to retain it and release it when it's done (because the function cannot assume that the object lives beyond the calling scope otherwise). Any function which uses an argument asynchronously (e.g. performSelector:withObject:afterDelay: etc.) does indeed retain the object and release it when it's done.
Alternately, think about it this way: How does ARC work? How does ARC know whether a function uses its argument synchronously or asynchronously? It doesn't. There is no annotation that tells the compiler whether a function uses something synchronously or asynchronously. Yet ARC does it correctly. That means you can too, without knowing whether the function uses its argument synchronously or asynchronously.

Pros & Cons of different ways to create a timer in Objective-C

From the documentation:
There are three ways to create a timer:
Use the scheduledTimerWithTimeInterval:invocation:repeats: or
scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: class
method to create the timer and schedule it on the current run loop in
the default mode.
Use the timerWithTimeInterval:invocation:repeats: or
timerWithTimeInterval:target:selector:userInfo:repeats: class method
to create the timer object without scheduling it on a run loop. (After
creating it, you must add the timer to a run loop manually by calling
the addTimer:forMode: method of the corresponding NSRunLoop object.)
Allocate the timer and initialize it using the
initWithFireDate:interval:target:selector:userInfo:repeats: method.
(After creating it, you must add the timer to a run loop manually by
calling the addTimer:forMode: method of the corresponding NSRunLoop
object.)
What are the pros and cons of the above methods, in terms of:
performance (memory consumption, etc)
ease of use (possibility to control/ start/ stop the timer in any point of program)
thread-safe
Look forward to your reply.

Using dispatch_after in SpriteKit, passing multiple arguments from another class

I was using performSelector to generate SKSpriteNodes after a random period of time, until a lot of people told me it was better to use dispatch_after.
What I have understood is that I need to create a function that will have the dispatch_after and then there it will point to another function that I want to do repeatedly. But this creates a problem to me. I need to pass two arguments to the method that creates the SKSpriteNodes from another class.
If I've understood correctly, in that class I need to call the method that has the dispatch_after so that it can perform the action repeatedly. Then, how would I do all of this? Do I need to pass those arguments multiple times? Also, I cannot addChild:the method that has the dispatch_after because it does not return a SKSpriteNode (the one that creates them does indeed). So, I'm really confused.

If performSelectorOnMainThread:waitUntilDone: is called from the main thread, when will it execute?

I'm programming an application that makes use of asynchronous web requests using NSURLConnection, so I have multiple threads running. To ensure that the main logic of my app happens on one thread, I am making heavy use of performSelectorOnMainThread:waitUntilDone:. Sometimes though, I am running this on the main thread, which piqued my curiosity.
If performSelectorOnMainThread:waitUntilDone: is called while in the main thread? Does it act the same as just performSelector:? What if waitUntilDone: is YES? What if it is NO?
EDIT: I have found that when waitUntilDone: is YES, the selector is executed (almost) immediately, but I cannot figure out when it is executed if waitUntilDone: is NO.
performSelectorOnMainThread:withObject:waitUntilDone:
is a method to deliver message on main thread of your application. Here boolean value in parameter waitUntilDone: specifies that whether you want to block your main thread to execute specified selector or not.
for example -
if you written these two lines-
[self performSelectorOnMainThread:#selector(print) withObject:nil waitUntilDone:YES];
NSLog(#"Hello iPhone");
and this is the print method -
- (void) print
{
NSLog(#"Hello World");
}
then you will get this o/p
Hello World
Hello iPhone
so it first pause the execution of your main thread and print "Hello World" and then execute main thread again and print "Hello iPhone" because you specified YES in waitUntilDone:
but if you specified NO in waitUntilDone: then it will print like this -
Hello iPhone
Hello World
it clearly indicates that it put your request of executing the specified selector in a queue and as OS gets its main thread free it executed you request.
Calling performSelectorOnMainThread:withObject:waitUntilDone: either from main thread or a secondary thread doesn't make any difference in it's execution, it depends on what you specified in waitUntilDone:
for more info -
NSObject Class Reference
If the current thread is also the main thread, and you pass YES,
the message is performed immediately, otherwise the perform is
queued to run the next time through the run loop.
If YES, it can be performed before performSelectorOnMainThread:withObject:waitUntilDone: returns.
I have found that when waitUntilDone: is YES, the selector is executed (almost) immediately, but I cannot figure out when it is executed if waitUntilDone: is NO.
The bit about the run loop: Your main thread has a run loop. This more or less prevents a thread from exiting. A run loop manages a todo list. When its work is complete, it suspends execution of that thread for some time. Then it wakes up later and sees if has work to do.
The amount of work can vary greatly (e.g. it may do some really heavy drawing or file i/o between the time it awakes and the point your selector is performed. Therefore, it's not a good tool for really precise timing, but it should be enough to know how it works and how the implementations adds the work to the run loop.
http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html
If waitUntilDone: is YES it acts as an immediate function call.
If waitUntilDone: is NO then it queues the call along with all other threads' calls.
This method queues the message on the run loop of the main thread
using the common run loop modes—that is, the modes associated with the
NSRunLoopCommonModes constant. As part of its normal run loop
processing, the main thread dequeues the message (assuming it is
running in one of the common run loop modes) and invokes the desired
method.
As noted above, things like drawing and I/O are prioritized over anything in queues. Once the main thread gets around to having time for queue service in the next event loop, there's a couple other details that make it not quite as simple as counting on first in first out:
1) dispatch_async() blocks ignore modes.
2) The performSelector variants with a specific mode argument -- event tracking, say -- may take precedence over ones with the default common modes argument in a loop running in that specific mode.
As a general rule, if you want predictable timing behaviours you should use the low level GCD dispatch functions that don't take account of higher level considerations like run loop modes.

Is there a setTimeout (like) in objective-c

Is there a similar setTimeout function in objective-c like in javascript? I dont want a sleep function.
I want to fire a "message" after a period of time gone by but no locking up the device.
Try NSTimer.
As Calvin points you can use NSTimer class.
As an alternative you can use performSelector:withObject:afterDelay: method to schedule method call after specific delay (note that it is not guaranteed that delay will be exactly you specified - it just will be not less than that value)
See NSObject's performSelector:withObject:afterDelay:. You can also use NSTimer — it's particularly useful for mimicking setInterval(). And to execute arbitrary code instead of just sending a message, see Grand Central Dispatch's dispatch_after.