scheduledTimerWithTimeInterval vs performselector with delay with iOS 5.0 - iphone

i am doing function call with scheduledTimerWithTimeInterval. i am just checking that xml parsing is completed or not for particular web services and invalidating timer in didEndElement method after getting successful response.
timerForStopWebService = [NSTimer scheduledTimerWithTimeInterval:30.0 target:self selector:#selector(stopWS) userInfo:nil repeats:NO];
now i am facing problem with iOS 5.0 and its working fine in other iOS versions. in iOS 5.0, a function stopWS call anytime even if i am invalidating it. let me know if you have solution for that.
and now i am implementing performselector with delay and set boolean variables in stopWS to identify that parsing is completed or not. i just want to know that is there any major difference between this? and does this solution works for my problem?
if other way exists, please suggest me, thanks.

Here are your differences
performSelectorWithObjectAfterDelay
as the name suggests performs a selector after a specified number of seconds. ONCE.
The care that you need to take here is that you need to cancel any previous perform requests before the object that the selector is being performed on is released. For that use the cancelPerformSelector method.
scheduledTimerWithTimeInterval
this method gives you the ability to call a selector after a specified duration too but it also has a parameter [repeats:] that lets you call the same selector REPEATEDLY
You can also pass in invocations to call selectors, which are specially helpful when your selector needs a lot of arguments.
You need to invalidate the timer when its no longer needed. This should do the trick
[myTimer invalidate]; myTimer = nil;
Also this is the most definitive thread on NSTimer, please have a look at it. How do I use NSTimer?

You can use performSelectorWithObjectAfterDelay and then cancelPerformSelector to abort it if no longer needed. I think this is easier than scheduledTimerWithTimeInterval since you don't need to store a reference to the timer. For the most part these two approaches should behave the same though.

Related

Fire method when a specific nsdate has passed

I want my App to call a method at an setter NSDate (It only needs to happen when the app is active, I'll handle passed events on launch in the app delegate).
I read about some ways to achieve such a behavior: On the one hand to work with performSelector:withObject:afterDelay: (But this doesn't look like a good way for me) or on the other hand to work with an NSTimer.
What is the best way regarding the app performance? One requirement is that you can cancel the event.
Using NSTimer is a simple solution. It has a property called fireDate that tells you when it's going to fire next. And it's a writeable property, so you can set that date to whatever you want.
Cancel the event by invalidating the timer object.

iPhone... Pause current thread between actions (non blocking)

I have a function that selects a row on a UITableView and then fires didSelectRowAtIndexPath to emulate the row having been clicked. This all happens very fast making it hard to see what has happened, I want to artificially pause between these actions so that it is more pleasing to the eye.
I implemented this using NSTimer using the following code however it only has a resolution as low as 1 second. I would ideally like to pause around 300 ms. How can I achieve as simply as possible?
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
I'm not sure I agree with calling didSelectRowAtIndexPath directly. I would suggest moving whatever you're doing in there to a separate method (say, selectionResponse:) and calling that directly.
Once you've done this, you can use performSelector:withObject:afterDelay: to call your selectionResponse: method, setting the afterDelay: argument to whatever value you want.
The link for the documentation on performSelector:withObject:afterDelay is here
Note that it's also a good idea to use + cancelPreviousPerformRequestsWithTarget:selector:object: (from the same document) in your dealloc, to cancel a pending perform request if your user chooses to back out of your view controller within the delay period, before the selector is invoked. This will prevent a crash.

How to schedule events programmatically in ios?

I have been tasked to write an app that allows a user to schedule emails to be sent out in future.
The user selects a date time from a date picker, composes the message and recipient and then schedules the event. When the date/time occurs the message is sent out.
Can someone guide me to how to get about scheduling lets say a text message. I know how to send a text message. Just was not sure on the scheduling aspect of things.
Any pointers will be much appreciated.
The first response will technically allow you to establish a timer that will fire every 2.5 seconds, however the original poster asked for a solution that would fire at a specific time. For that you need to use the following method of NSTimer:
- (id)initWithFireDate:(NSDate *)date interval:(NSTimeInterval)seconds target:(id)target selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)repeats
The first argument is an NSDate indicating when the timer should fire.
The original poster did not specify, but if this is an iOS app then it is important to understand that timers scheduled to fire at a distant date/time will not fire if your app is not the foreground app. In fact there is no way to schedule such an event to occur when your app is in the background on iOS, so you must take that into account.
Here's a snippet of code which sets a one use timer to call self's imageSavedLabelOff: selector with itself (the timer) as the object parameter to the method. The timer schedules the call to be made in 2.5 seconds.
NSTimer *quickie = [NSTimer scheduledTimerWithTimeInterval:2.5 target:self selector:#selector(imageSavedLabelOff:) userInfo:nil repeats:NO];
You may have already found the answer by now but for future visiters like me I would like to suggest an answer- i.e. EventKit :
https://developer.apple.com/library/ios/documentation/DataManagement/Conceptual/EventKitProgGuide/ReadingAndWritingEvents.html
You can schedule/fetch events for any time and do your stuff accordingly. Hope this helps somebody.
You should be able to achieve this using NSRunLoop. Check out the Threading Programming Guide.
Apart from the use of NSTimer, you should be aware that sending of the E-Mail can fail for several reasons (no network available and others). Then you need to reschedule the request, maybe give up after 3 retries and notify the user about this.
You can use -
[self performSelector:#selector(myFunc:) withObject:nil afterDelay:5.0];

Touch handling not responding after NSTimer invalidate

I am creating a repeating NSTimer object that calls the -Loop() method every iteration of the run loop:-
NSTimer *loopTimer = [NSTimer scheduledTimerWithTimeInterval:TIMER_INTERVAL target:self selector:#selector(Loop) userInfo:nil repeats:YES];
Within Loop() I am invalidating the timer when it becomes necessary:-
[loopTimer invalidate];
However, after using -invalidate(), the Touch handling methods -touchesBegan(), -touchesEnded() stop responding to touch events. Does NSTimer affect the run loop to somehow?
what else you are using in loop method...
I am not sure what problem exactly you have.Anyway try this...
You can use schedular method..
[self schedule:#selector(loop) interval:TIMER_INTERVAL];
If you unscheduling with in the same function,you can use
[self unschedule:_cmd];
otherwise,
You can use [self unschedule:#selector(loop)];
This sounds like you didn't correctly retain the view or have released it once too often. A NSTimer retains its target object, and once you invalidate a timer it releases its target object. In your case, that seems to make the retain counter drop to 0 and it thus gets deallocated.
You can verify this by adding a NSLog right in front of your [loopTimer invalidate]; and another one at the start of your view's dealloc. My bet is that you will see dealloc's log message immediately after your invalidate log.
No, it doesn't affect your runloop in anyway. Infact I checked it myself, after i invalidated the timer i was able to process touches on screen.So i guess problem is something else.
I seem to have fixed the problem by putting -invalidate() inside the -dealloc() method. So when i want end the loop i call [self.view removeFromSuperView] and this calls invalidate eventually.
Putting -invalidate() inside view lifecyle seems to deallocate the view...

Having issues with iPhone NSTimer invalidation

Okay so I know I asked a similar question a while ago, but this is different. I now have two timers that go off on the TouchDown event of their respective buttons. On the TouchUpInside event I have respective code that tells each timer to [pressTimer invalidate] and pressTimer = nil. The problem that happens now since I added the second timer is that when the selector is triggered (thus releasing the button and triggering the TouchUpInside event) the app crashes and spits out an Not recognized [NSCFTimer -invalidate] or something like that. The buttons work normally, until the timer triggers, and even then no crash until I let up my finger. I think what's going on is that the TouchUpInside event is trying to invalidate an invalid/triggered timer, because it works fine while the timer is still running. I wonder why this is happening since it never happened before I added the second timer. My temporary fix is to set the repeating:YES portion of the timer, which supports my theory that it can't invalidate an invalid/triggered timer. Any suggestions?
*Bonus: On a related note, how many crashes do I need to get from people before they show up in iTunes Connect?
For one thing, the pressTimer=nil serves no purpose; nil assignment only releases objects when using a setter, on a retained property, i.e. self.timer = nil;. (this actually does: [self setTimer:nil]!)
But even then, if you misquoted yourself and did use a setter, an NSTimer instance need not be released, it only needs to be invalidated. Your "kind of quoted" error should not happen.
As for you theory: you may read invalidate as release in this context - you can't do it too often...
The manual states that invalidate needs to be called from the same thread where it was installed, beyond that there's really no reason for anything to crash.