I have set a function in a selector. After a function call I want to not call selector. I wrote this line of code but it is throwing an exception:
self.touchselector = nil;
How can I reset the function of selector in cocos2d?
Try this one:
[NSNotification cancelPreviousPerformRequestsWithTarget:self selector:#selector(powerHide) object:nil];
Assuming you scheduled a selector similarly to this:
[self scheduleSelector:#selector(onTouch:) interval:1];
Then you can unschedule that particular selector in the method that it calls via _cmd:
-(void) onTouch:(ccTime)delta
{
// this will stop onTouch from being called every second
[self unscheduleSelector:_cmd];
}
Related
I'm having a problem writing a class method wich have a method has argument.
The function is inside the class "SystemClass.m/h"
//JSON CALL
+(void)callLink:(NSString*)url toFunction:(SEL)method withVars:(NSMutableArray*)arguments {
if([self checkConnection])
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *datas = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
[arguments addObject:datas];
[self performSelectorOnMainThread:#selector(method:) withObject:arguments waitUntilDone:YES];
});
}else{
[self alertThis:#"There is no connection" with:nil];
}
}
What the function does is to call a JSON url, and give data to a Method
I use it like this:
[SystemClass callLink:#"http://www.mywebsite.com/call.php" toFunction:#selector(fetchedInfo:) withVars:nil];
but it crashes like this:
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '+[SystemClass method:]:
unrecognized selector sent to class 0x92d50'
May you help me please? I'm trying to found the solution anyway!
Thanks, Alex
In you callLink method you already give a selector as argument (it's the argument called "method"). Moreover you need to add one more argument, because the "method" argument should be invoked from an object that implement this method (and in the example you give us, the applicaiton will try to call the method named "method" from SystemClass when you call :
[self performSelectorOnMainThread:method withObject:arguments waitUntilDone:YES];
Here self is the SystemClass and a such method doesn't seem to exist in SystemClass, that's why it is crashing). So add a target (an id object) to the arguments :
+(void)callLink:(NSString*)url forTarget:(id) target toFunction:(SEL)method withVars:(NSMutableArray*)arguments;
So for the following line you should just give the selector and call this selector on the target object :
[target performSelectorOnMainThread:method withObject:arguments waitUntilDone:YES];
And not :
[self performSelectorOnMainThread:#selector(method:) withObject:arguments waitUntilDone:YES];
Improvement :
Before calling the selector you should check if the target responds to the selector doing something like that (it'll prevent your application from crashing). Instead of doing this :
[target performSelectorOnMainThread:method withObject:arguments waitUntilDone:YES];
Do this :
if([target respondsToSelector:method])
{
[target performSelectorOnMainThread:method withObject:arguments waitUntilDone:YES];
}
else
{
//The target do not respond to method so you can inform the user, or call a NSLog()...
}
I've added an observer for my method:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(closeViewAfterUpdating)
name:#"labelUpdatedShouldReturn"
object:nil];
Then my relevant methods:
-(void)closeViewAfterUpdating; {
NSLog(#"Part 1 called");
[self performSelector:#selector(closeViewAfterUpdating2) withObject:nil afterDelay:2.0];
}
-(void)closeViewAfterUpdating2; {
NSLog(#"Part 2 called");
[self dismissModalViewControllerAnimated:YES];
}
The only reason why I've split this method into two parts is so that I can have a delay before the method is fired.
The problem is, the second method is never called. My NSLog output shows Part 1 called, but it never fires part 2. Any ideas?
EDIT: I'm calling the notification from a background thread, does that make a difference by any chance?
Here's how I'm creating my background thread:
[NSThread detachNewThreadSelector:#selector(getWeather) toTarget:self withObject:nil];
and in getWeather I have:
[[NSNotificationCenter defaultCenter] postNotificationName:#"updateZipLabel" object:textfield.text];
Also, calling:
[self performSelector:#selector(closeViewAfterUpdating2) withObject:nil];
does work.
EDITx2: I fixed it. Just needed to post the notification in my main thread and it worked just fine.
The background thread is the problem. It has a non running run loop, thus the selector is never called. Just let the NSRunLoop or CFRunLoopRef object of the thread run while the selector isn't fired.
I tried your code and it works fine on my side. You might be doing something funky in the background that is interrupting your selector.
You have a semi-colon in the method definition:
-(void)closeViewAfterUpdating2; {
Is this present in the code or a copy/paste issue? That would be the problem on why you never see it called.
My main view PlayGameViewController has a subview (actually 2 of them) called CardViewController.
CardViewController creates some buttons programmatically
-(void) initialiseButtons
{
NSLog(#"initialiseButtons %d",totalButtons);
int ypos = playerImage.frame.origin.y + playerImage.frame.size.height + 42;
for(int i=0; i<totalButtons; i++)
{
StatView *sv = [[StatView alloc] initWithYPos:ypos];
sv.tag = 100 + i;
[sv.overlayButton addTarget:self action:#selector(statTapped:)
forControlEvents:UIControlEventTouchUpInside];
sv.overlayButton.tag = 10 + i;
[self.frontView addSubview:sv];
ypos += 26;
}
}
It sets a callback function statTapped. This works ok and the function does get called.
But... All the game logic is in PlayGameViewController so I need to handle the function there. I tried deleting the function from CardViewController and implementing it instead in the PlayGameViewController but the call wasn't passed down to the parent class.
Is there away to achieve this or am I talking and thinking crazy?
I think you have a couple of options:
Create a delegate to process your statTapped: method. You can learn more about delegates and how to create one here: How do I create delegates in Objective-C?
Use NSNotification and add a listener in PlayGameViewController that will call the statTapped: method (also defined in PlayGameViewController. Then in CardViewController have your selector action call a method that posts a notification. PlayGameViewController will receive that notification and then run the specified tasks.
Here is an example of using NSNotification:
In your PlayGameViewController's init method, write:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(statTapped:)
name:#"statTapped"
object:nil];
In CardViewController, you'll want to set a selector to your button action as you do now, but instead of statTapped: you'll want a different method which contains this code:
[[NSNotificationCenter defaultCenter] postNotificationName:#"statTapped"
object:self];
By doing so your PlayGameController will own the statTapped method.
Don't forget to remove the observer in your viewDidUnload method:
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"statTapped" object:nil];
I am a little perplexed and I have been working on this for hours and googling without any real leads. I want to create a callback in objective-c for my iPhone app utilizing the #selector.
Class 1:
- (void) someMethod {
// create selector
SEL successCallback = #selector(successMethod);
// call some service with caller and selector
[class2 dispatchSomeEvent:self callback:successCallback];
// here's the call back method
- (void) successMethod {
NSLog(#"Callback success");
}
}
Class 2:
// some event
- (void) dispatchSomeEvent:(id) caller selector:(SEL) successCallback {
// catch the event and execute callback
if ([caller respondsToSelector:successCallback]) {
[caller successCallback];
}
}
The conditional respondsToSelector will pass but the callback on the next line will fail. HOWEVER, if I would do like this:
// catch the event and execute callback
if ([caller respondsToSelector:successCallback]) {
[caller successMethod];
}
So instead of using the selector I passed, I type in the method name directly... and it works!
The error I get is this:
unrecognized selector sent to instance
0x6c37f70
What is going on here??
Thanks in advance!
You should call your selector using -performSelector method:
if ([caller respondsToSelector:successCallback]) {
[caller performSelector:successCallback];
}
Ok, I've spend like half day on this and it's killing me.
So I've got 3 view controllers transitioning from one another, something like this:
I call the UploadDecisionViewController after destroying the previous View Controller:
[self dismissModalViewControllerAnimated:YES];
[self performSelector:#selector(showUDModalView) withObject:nil afterDelay:0.5];
In my showUDModalView method:
- (void)showUDModalView
{
UploadDecisionViewController *udcontroller = [[UploadDecisionViewController alloc] initWithNibName:#"UploadDecisionViewController" bundle:nil];
udcontroller.delegate = self;
[self presentModalViewController:udcontroller animated:YES];
[udcontroller release];
}
The UploadDecisionViewController shows up no problem. The UploadDecisionViewController has a button, which when clicked I want it to transition to the FileUploadViewController. I setup a UploadDecisionDelegate, threw a method in there to handle the button clicking:
Inside UploadDecisionDelegate protocol (UploadDecisionViewController.h):
#protocol UploadDecisionDelegate
//let UOnliveViewController know that a button was selected
- (void)UploadDecisionViewController:(UploadDecisionViewController *)controller madeChoice:(NSString *)whichDirection;
#end
Then inside my IBAction method when the button is clicked, I have this:
- (IBAction)decisionSelected:(id)sender
{
[delegate UploadDecisionViewController:self madeChoice:#"upload"];//crashing at this line
}
When I run this, at this line above it is throwing a runtime exception:
2010-06-09 12:48:59.561 UOnlive[4735:207] *** -[UIView UploadDecisionViewController:madeChoice:]: unrecognized selector sent to instance 0x3b65420
2010-06-09 12:48:59.562 UOnlive[4735:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[UIView UploadDecisionViewController:madeChoice:]: unrecognized selector sent to instance 0x3b65420'
2010-06-09 12:48:59.563 UOnlive[4735:207] Stack: (
33502299,
2495698185,
33884219,
33453686,
33306306,
20618,
2982917,
3390286,
3399023,
3394235,
3087839,
2996168,
3022945,
40156505,
33287040,
33283144,
40150549,
40150746,
3026863,
11700,
11554
)
Let me throw in the delegate method implemented also:
- (void)UploadDecisionViewController:(UploadDecisionViewController *)controller madeChoice:(NSString *)whichDirection
{
NSLog(#"it got to here 245");
[self dismissModalViewControllerAnimated:YES];
if (yesOrNo) {
//open up the FileUploadViewController and proceed to upload
[self performSelector:#selector(showFUModalView) withObject:nil afterDelay:0.5];
}
}
Can someone tell me what the heck is going on? Thanks a bunch for the help...
The error says that you are trying to call the UploadDecisionViewController method on UIView.
My bet is that you set some view to the delegate instead of view controller.
Where the showUDModalView method is located?
Maybe you set the delegate in some additional places?
Your code is to lengthy and I dont want to go through this but just an advice, you can c if your object can/cannot perform a selector with this kind of statement:
if([myObj respondsToSelector:#selector(myFunc)])
{
//do something
}
else{
//do something else
}