whats the proper way of passing an argument to NSTimer
-
Im using a basic timer that calls a method which is defined as below: - (void) refresh:(id)obj { if (obj == YES) doSomething; } I want to call this method from certain areas of my code and also from a timer [NSTimer scheduledTimerWithTimeInterval:refreshInterval target:self selector:@selector(refresh:) userInfo:nil repeats:YES]; When I put YES as the argument for the userInfo parameter I get an EXEC_BAD_ACCESS error why is this? Can someone help me do this the right way so that there is no ugly casting and such? Thanks Mark
-
Answer:
The userInfo parameter must be an object; it is typed id. YES is a primitive, namely the value 1. In order to make sure the userInfo object does not get deallocated, the timer retains it. So, when you passed YES, NSTimer was doing [(id)YES retain]. Try that in your own code and see what happens. :-P As the http://developer.apple.com/iphone/library/documentation/cocoa/reference/foundation/Classes/NSTimer_Class/Reference/NSTimer.html#//apple_ref/occ/clm/NSTimer/scheduledTimerWithTimeInterval%3atarget%3aselector%3auserInfo%3arepeats%3a states, the selector you give the method must have the signature - (void)timerFireMethod:(NSTimer*)theTimer This means you can't have an NSTimer invoke just any method—not directly at least. You can make a special method with the above signature which in turn invokes any method you want though. So, say you have a method called refresh:, and you want to call it every so often, passing it YES. You can do this like so: // somewhere { [NSTimer scheduledTimerWithTimeInterval:refreshInterval target:self selector:@selector(invokeRefresh:) userInfo:nil repeats:YES]; } - (void)invokeRefresh:(NSTimer *)timer { [self refresh:YES]; } - (void)refresh:(BOOL)flag { if (flag) { // do something } }
Mark at Stack Overflow Visit the source
Other answers
In Objective-C, a primitive type is not an object. So you can't directly pass it to an argument which expects an id, which stands for a generic object. You need to wrap it into an NSNumber object. Use NSTimer*timer=[NSTimer scheduledTimerWithTimeInterval:refreshInterval target:self selector:@selector(refresh:) userInfo:[NSNumber numberWithBool:YES] repeats:YES]; and - (void) refresh:(NSTimer*)timer { NSNumber* shouldDoSomething=[timer userInfo]; if ([shouldDoSomething boolValue]) doSomething; } Don't forget to invalidate and release the timer once it's done. By the way, you don't have to compare a BOOL (or C++ bool) against YES or true or whatever. When you write if(a>b) { ... } a>b evaluates to a bool, and if uses the result. What you're doing there is like if((a>b)==YES) { ... } which is quite strange to me. It's not that the (..) after if should contain a comparison; it should contain a bool.
Yuji
As a follow-up to kperryua's answer, if you want to pass a primitive through userInfo you can box it with NSNumber or NSValue; in the case of a boolean, you'd want to use [NSNumber numberWithBool:YES], then call boolValue in the timer callback to get back the primitive.
smorgan
Related Q & A:
- What is the proper way to do an abdominal crunch?Best solution by exercise.about.com
- Whats the best way to advertise online for a small business?Best solution by Yahoo! Answers
- What is the proper way to open a laptop lid?Best solution by Yahoo! Answers
- What Is The Proper Way To Minimize The Screen While Playing The Sims2 PC?Best solution by modthesims.info
- What is the best and proper way to study for an AP Exam?Best solution by Yahoo! Answers
Just Added Q & A:
- How many active mobile subscribers are there in China?Best solution by Quora
- How to find the right vacation?Best solution by bookit.com
- How To Make Your Own Primer?Best solution by thekrazycouponlady.com
- How do you get the domain & range?Best solution by ChaCha
- How do you open pop up blockers?Best solution by Yahoo! Answers
For every problem there is a solution! Proved by Solucija.
-
Got an issue and looking for advice?
-
Ask Solucija to search every corner of the Web for help.
-
Get workable solutions and helpful tips in a moment.
Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.