method calling problem - objective-c

i've got this method:
-(void)reportAchievementIdentifier: (NSString*) identifier percentComplete: (float) percent
now I want to call this method in another method like:
[self thisMethod];
But how can I do this with a method that has local declarations in it?
thank you

It doesn't matter if a method has local declarations in it, that's completely normal. Have you tried calling [self thisMethod];? Does it crash?

Related

Implicit declaration of function "..." is invalid in C99?

I'm trying to declare a function within another function. So here's part of my code:
ViewController.m
- (void)updatedisplay{
[_displayText setText:[NSString stringWithFormat:#"%d", counter]];
}
- (IBAction)minus1:(id)sender {
counter--;
updatedisplay();
}
ViewController.h
- (IBAction)minus1:(id)sender;
- (void)updatedisplay;
Which returned me the error of "Implicit declaration of function "..." is invalid in C99".
Result: http://i.imgur.com/rsIt6r2.png
I've found that people have encountered similar problem, but as a newbie I didn't really know what to do next. Thanks for your help! :)
Implicit declaration of function '...' is invalid on C99
You are not declaring a function; but a instance method, so to call it you must send it as a message to self;
[self updatedisplay];
EDIT
As #rmaddy pointed out (thanks for that) it is declared as instance method not class method. To make the things clear;
- (return_type)instance_method_name.... is called via 'self' or pointer to object instance.
+ (return_type)class_method_name.... is called directly on the class (static).
Problem
updatedisplay();
solution
[self updatedisplay];
cause
- (void)updatedisplay;
is a class method available for that class.So you have to call from the class to have the method available for you.
That is because you defined your function as a instance method, not a function.
So use it like
- (IBAction)minus1:(id)sender {
counter--;
[self updatedisplay]; // Change this line
}
write this way :
[self updatedisplay];

Selectors in Cocos2d schedule method

So I am doing this to initialize my selector:
//In .h
SEL selectors[3];
//In .m
selectors[0] = #selector(rotate);
selectors[1] = #selector(discharge);
And here is the problem:
When I call this in my init method in Cocos2d like this:
[self performSelector:selectors[0]];
it works fine, but when I call this line of code in a method called moveThings which is invoked through the schedule ([self schedule:#selector(moveThings:)]) at the end of my init method in Cocos2d it gives EXC_BAD_ACCESS. What is the problem with scheduling things?
UPDATE:
I have found there is a problem with the rotate function (the function being stored in selector[0]). Here it is:
-(void)rotate:(ccTime)delta {
if (((CCSprite *)[creature objectAtIndex:0]).rotation < 360) {
((CCSprite *)[creature objectAtIndex:0]).rotation++;
}
else {
((CCSprite *)[creature objectAtIndex:0]).rotation++;
}
}
If I comment the contents of the method out it works fine when called through moveThings and init.
If I change the methods contents with:
((CCSprite *)[creature objectAtIndex:0]).rotation++;
It fails... But, again, I would like to state that all of these things do work if I call it in my init method, even call it twice in a row, but it will not work (except when I take out the contents of the rotate method) if I call it through the moveThings: method which is being invoke through the schedule method it fails.
Further update:
If I call:
((CCSprite *)[creature objectAtIndex:0]).rotation++;
In moveThings (which is being, as I've said before, invoked by the schedule:(SEL) method) it fails. Where as long as it is not invoked through a method that is the called by schedule it works.
The problem is that when you call performSelector there are only two options:
have your selector take no arguments and leave the ":" off the #selector(foo) definition.
have your selector take either one or two arguments which both must be an NSObject or subclass
it is the latter that is messing you up here I suspect.
Here are the three forms of performSelector:
- (id)performSelector:(SEL)aSelector;
- (id)performSelector:(SEL)aSelector withObject:(id)object;
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
You'll note that the withObject arguments are all of type id which is an Objective C object.
The selector you're trying to use takes a ccTime which is a float and not an Objective C object as it's param and that is why things are crashing:
-(void)rotate:(ccTime)delta;
One option is to make a wrapper method that takes a wrapped ccTime and unwraps it and calls the rotate:(ccTime) method:
- (void) wrappedRotate: (NSNumber*) inDelta
{
[self rotate: [inDelta floatValue]];
}
then use
selectors[0] = #selector(wrappedRotate:);
and then call via:
[self schedule: #selector(moveThings:)]); // cocos2d schedule
...
- (void) moveThings: (ccTime) dt
{
[self performSelector: selectors[0] withObject: [NSNumber numberWithFloat: dt]];
...
}
One reason you are getting confused is because Cocos2d is using #selector in somewhat more complicated ways (see CCScheduler.m in the CCTimer::initWithTarget:selector:interval: and CCTimer::update: method in particular).
disclaimer: code typed into SO so not checked with a compiler, but the essence of what you need should be here.
One problem for sure is that you are using a variable declared inside a .h while initializing it inside the relative .m. According to the linking I'm not sure that just one variable selectors will exist (so that different files that include .h will have different versions).
First of all I suggest you to try adding the keyword extern to have
extern SEL selectors[3];
to tell your linker that it is initialized inside the relative .m and to use just that one.
I think your problem stems from your method definition which is - (void)rotate; and not - (void)rotate:(ccTime)dt;
You should adjust your selectors likewise.
If your method does not have any arguments then do not use a colon in your selector call.
// Requires #selector(foo:)
- (void) foo:(id)sender;
// Requires #selector(foo)
- (void) foo;

How could I pass the float number by value in Objective-C?

In the following code, I passed the "1.3f" to printFloat, but it was the wrong value (in this case, -2.000000) after was "f" received. And there is a warning that "AppDelegate may not respond to -printFloat:"
Where did I get it wrong?
- (void)applicationDidFinishLaunching:(UIApplication *)application{
// Override point for customization after application launch
[window makeKeyAndVisible];
[self printFloat:1.3f];
}
- (void)printFloat:(float)f {
NSLog(#"%f",f);
}
You can easily resolve both your problems by adding the method prototype into the header file (<sameName>.h):
- (void)printFloat:(float)f;
If you include the correct definition in the class' header file, and you still cannot pass floats by reference, make sure you're not overriding an existing method of a parent class...
For example, I had this problem because my class was derived from NSMutableData (which I did not know then), and I added a method,
- (void) initWithLength:(float)length;
to my class. NSMutableData already defines this method, and it uses an integer.
My method then produced garbage: the float value was passed as 0x0 no matter what I sent it...

Subclassing and Casting in Objective C

I came across a strange problem today. I created a subclass of UIView and added only 1 method to the template code provided by xcode.
#interface FloatView : UIView {
}
- (void)floatTest:(CGFloat)x;
#end
- (void)floatTest:(CGFloat)x {
NSLog(#"float was %f", x);
}
Then in my appDelegate I had code like this:
UIView *floatView = [[FloatView alloc] init];
[floatView floatTest:10.0f];
Pretty simple, right? What should this print out? I thought it would something like "10.0000", but no, it prints out "0.000000".
I wrestled with this for hours, trying to figure out what I was doing wrong, and then I changed the code in my appDelegate to
FloatView *floatView = [[FloatView alloc] init];
[floatView floatTest:10.0f];
Only then, did it print out the expected "10.0000". Why is this so? I've declared FloatView as a subclass of UIView, shouldn't I be able to assign a FloatView object to a UIView pointer without problems?
Even though floatView was declared a pointer to a UIView, it's really a floatView and it should be able to handle the floatTest message? Am I totally off base here?
Actually, polymorphism is working as expected. If it didn't work, nothing would have been printed (in your example, 0.0000 is being printed). The thing is, while your instance actually responds to testFloat:10.0f message, since the compiler can't statically see the method declaration (as UIView class doesn't declare such a method), it assumes that your method takes ... as argument and returns id.
When CGFloat is passed to a method that expects variable number of arguments (...), it's promoted to double. Thus, the receiving method is passed a double argument and thinks it's a float and it doesn't get printed correctly.
You can verify this behavior by changing NSLog line to:
NSLog(#"%f", *(double*)&x);
When the compiler sends the message to FloatView* rather than a UIView*, it can find the exact signature of the method. It can see it really expects CGFloat and doesn't promote the argument to double. As a result, it works correctly.
Additionally, if UIView* contained the method declaration that took a CGFloat, the compiler would call the method appropriately. To summarize, this is not a polymorphism issue; it's a missing method signature issue.

How can I call a method in Objective-C?

I am trying to build an iPhone app. I created a
method like this:
- (void)score {
// some code
}
and I have tried to call it in an other method like this:
- (void)score2 {
#selector(score);
}
But it does not work. So, how do I call a method correctly?
To send an objective-c message in this instance you would do
[self score];
I suggest you read the Objective-C programming guide
Objective-C Programming Guide
I suggest you read The Objective-C Programming Language. The part about messaging is specifically what you want here, but the whole thing will help you get started. After that, maybe try doing a few tutorials to get a feel for it before you jump into making your own apps.
calling the method is like this
[className methodName]
however if you want to call the method in the same class you can use self
[self methodName]
all the above is because your method was not taking any parameters
however if your method takes parameters you will need to do it like this
[self methodName:Parameter]
I think what you're trying to do is:
-(void) score2 {
[self score];
}
The [object message] syntax is the normal way to call a method in objective-c. I think the #selector syntax is used when the method to be called needs to be determined at run-time, but I don't know objective-c well enough to give you more information on that.
Use this:
[self score]; you don't need #sel for calling directly
syntax is of objective c is
returnObj = [object functionName: parameters];
Where object is the object which has the method you're calling. If you're calling it from the same object, you'll use 'self'. This tutorial might help you out in learning Obj-C.
In your case it is simply
[self score];
If you want to pass a parameter then it is like that
- (void)score(int x) {
// some code
}
and I have tried to call it in an other method like this:
- (void)score2 {
[self score:x];
}
use this,
[self score];
instead of #selector(score).
[self score]; instead of #selector(score)