views:

790

answers:

3

Hello,

I've looked at this over and over again and I can't see the problem. Its probably obvious and I'm probably being an idiot and I apologize in advance for this.

In my interface I have:

@interface PolygonShape : NSObject 
{
    int numberOfSides;
    int minimumNumberOfSides;
    int maximumNumberOfSides;

}

@property int numberOfSides, minimumNumberOfSides, maximumNumberOfSides;

// class methods
+ (float)getAngleInDegrees:(PolygonShape *) polyshape;
+ (float)getAngleInRadians:(PolygonShape *) polyshape;
+ (NSString)getName:(PolygonShape *) polyshape;

//instance methods
- (id)init;
- (id)initWithNumberOfSides:(int)sides minimumNumberOfSides:(int)min 
       maximumNumberOfSides:(int)max;
@end

The part in the implementation that I get errors is for the getName method:

@implentation...

+ (NSString)getName:(PolygonShape *) polyshape
{
// here is where I get the "error: can not use an object as parameter to a method"
    int sides = [polyshape numberOfSides];
    NSString * s = [NSString init];

    switch (sides) {
     case 3:
      s = "@Triangle";
// there's also an "assignment from incompatible pointer type" warning...but its secondary
      break;
     case 4:
      return "@Square";
      break;

     default:
      break;
    }
}

The thing that drives me batty is that the class methods works just fine: + (float)getAngleInDegrees:(PolygonShape *) polyshape; + (float)getAngleInRadians:(PolygonShape *) polyshape;

ube

+4  A: 

Your getName: method should return (NSString *), not (NSString). I assume this is the error; if so, then yes, the error message could definitely have been more informative.

In fact, in Objective-C you will never see objects getting passed around without their * behind them, not as return values, not as parameters, not as local variables and not as member variables.

BTW, the warning you mention is because you have a typo, mixing up "@foo" with @"foo". The latter is an Objectice-C string literal, the former is a C string literal whose first character just happens to be @.

harms
You're absolutley right on both counts. Thanks you for helping save my sanity.You right - I'm passing the pointer not the object which I have to indicate with the *. I don't understand why it also makes a difference if its (NSString *) foo or (NSString ) *foo (wouldn't the second form be more correct in showing foo to be a pointer.
I'm not sure about the details, but the way I think about it is that as long as you're dealing with ObjC classes, the parentheses and the asterisk are just a special syntax meant to resemble C's pointer syntax. So the ObjC parser handles them with special rules. That might not be technically correct, but probably a good way to think about it while learning.
harms
ube: The * is part of the type specification, and the whole type specification must be inside the ().
Peter Hosey
Thanks harms and Peter - I'll keep that in mind. Especially that "objective C" is not "C" - its obvious...but the syntactic nuances can cause quite a bit of trip ups.
+1  A: 

I think the error is slightly misleading in this case. In Objective-C, it's generally not possible to pass an object by value (including return values). In this case, you declare the return value as NSString rather than NSString*. The declaration should be:

+ (NSString*)getName:(PolygonShape *) polyshape

not

+ (NSString)getName:(PolygonShape *) polyshape
Barry Wark
Thank you Barry - you're right. I'm passing a pointer back to an object.
+3  A: 

In addition to the other answers, you're using [NSString init] where you should be using [[NSString alloc] init]. However, that will only allocate an empty string, so you'd probably be better off initializing s to either @"" or nil.

Jim Dovey
Good point - thanks Jim.