Obj C question

Discussion in 'Mac Programming' started by phanfave, Aug 6, 2008.

  1. phanfave macrumors newbie

    Joined:
    Jul 10, 2008
    #1
    Hi everyone,

    I'm working my way though Kochan's Obj C book and have hit a few snags. I'm thinking my problems have to deal with Obj C 2.0 not fully compatible with what's in the book. I've got an object Rectangle where I'm setting the origin of the object. The method to do this is:

    -(void) setOrigin: (Point *) pt
    {
    origin = pt;
    }

    I've got a Point class identified and refer to the definition in the main program. This works fine. Then he has us instead have the method allocate it's own point by changing the method to this:
    {
    origin = [[Pointxy alloc] init];
    [origin setX: [pt x] andY: [pt y]];
    }

    When I do this I get these errors:
    2008-08-06 09:40:39.191 Objective-C[4547:10b] *** NSInvocation: warning: object 0x5c09a00 of class 'Pointxy' does not implement methodSignatureForSelector: -- trouble ahead
    2008-08-06 09:40:39.194 Objective-C[4547:10b] *** NSInvocation: warning: object 0x5c09a00 of class 'Pointxy' does not implement doesNotRecognizeSelector: -- abort

    I changed the rectangle class to import the Pointxy class. I think that this should work but it's not. Anyone have any ideas? If needed I can post my headers and source files. I'm really stuck here and can't figure this out on my own. Thanks for any input offered.

    Sean
     
  2. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #2
    Post Pointxy.m and Pointxy.h so we can see what you've defined there.... from this code you posted you need to define:
    -init
    -setX:andY

    and you need to be sure that your class is subclassing NSObject, otherwise there will be rough waters ahead.

    -Lee
     
  3. phanfave thread starter macrumors newbie

    Joined:
    Jul 10, 2008
    #3
    Thanks for the quick reply. Here are the header files:
    Pointxy.h
    #import <objc/Object.h>

    @interface Pointxy: Object
    {
    int x;
    int y;
    }

    -(void) setX: (int) xVal;
    -(void) setY: (int) yVal;
    -(void) setX: (int) xVal andY: (int) yVal;
    -(int) x;
    -(int) y;
    @end

    Rectangle.h
    #import <objc/Object.h>
    #import "Pointxy.h"

    @interface Rectangle: Object
    {
    int width;
    int height;
    Pointxy *origin;
    }

    -(void) setWidth: (int) w;
    -(void) setHeigh: (int) h;
    -(void) setWidth: (int) andHeight: (int) h;
    -(void) setOrigin: (Pointxy *) pt;
    -(Pointxy *) origin;
    -(int) width;
    -(int) height;
    -(int) area;
    -(int) perimeter;
    @end

    And here are the source files:
    Point.m
    #import "Pointxy.h"
    @implementation Pointxy;

    -(void) setX: (int) xVal
    {
    x = xVal;
    }

    -(void) setY: (int) yVal
    {
    y = yVal;
    }

    -(void) setX: (int) xVal andY: (int) yVal
    {
    x = xVal;
    y = yVal;
    }

    -(int) x
    {
    return x;
    }

    -(int) y
    {
    return y;
    }

    @end

    Rectangle.m
    #import "Rectangle.h"
    #import "Pointxy.h"

    @implementation Rectangle;

    -(void) setWidth: (int) w
    {
    width = w;
    }

    -(void) setHeight: (int) h
    {
    height = h;
    }

    -(void) setWidth: (int) w andHeight: (int) h
    {
    width = w;
    height = h;
    }

    -(int) width
    {
    return width;
    }

    -(int) height
    {
    return height;
    }

    -(int) area
    {
    return (width * height);
    }

    -(int) perimeter
    {
    return (2 * width + 2 * height);
    }

    -(void) setOrigin: (Pointxy *) pt
    {
    origin = [[Pointxy alloc] init];
    [origin setX: [pt x] andy: [pt y]];
    //origin = pt;
    }

    -(Pointxy *) origin
    {
    return origin;
    }

    @end

    Main.m
    #import "Rectangle.h"
    #import "Pointxy.h"
    #import <stdio.h>

    int main (int agrc, char *agrv[])
    {
    Rectangle *myRect = [[Rectangle alloc] init];
    Pointxy *myPoint = [[Pointxy alloc] init];

    [myPoint setX: 100 andY: 200];

    [myRect setWidth: 5 andHeight: 8];
    [myRect setOrigin: myPoint];

    printf ("Rectangle w = %i, h = %i\n",
    [myRect width], [myRect height]);

    printf ("Origin at (%i, %i)\n",
    [[myRect origin] x], [[myRect origin] y]);

    printf ("Area = %i, Perimeter = %i\n",
    [myRect area], [myRect perimeter]);

    //[[myRect origin] free];
    [myRect free];
    [myPoint free];
    }

    Fo a little background. I've just finished the Programming in C book for a class I took online. I've got a month downtime before classes start up again and wanted to spend this time learning Obj C and hopefully some Cocoa. If you see a comment like // that means I commented it out trying to figure this problem out. I'm sure this is a simple fix I just can't see it. Again thanks for your help.

    Sean
     
  4. gnasher729 macrumors P6

    gnasher729

    Joined:
    Nov 25, 2005
    #4
    I'd recommend to make everything based on NSObject, not Object. You shouldn't be using Object unless you have an excellent understanding of Objective-C and have a really good reason to do so.
     
  5. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #5
    It looks like the error is, as gnasher stated, being caused by subclassing Object instead of NSObject. The runtime depends on methods defined by NSObject, and it doesn't have access to these.

    I'm not sure on the book you're using, it may be teaching you to use Object instead... but you are definitely going to run in to problems. I don't know enough to say if some of these dependencies were introduced with Objective-C 2.0, but one way or the other, just subclass NSObject and you should be ok.

    Also, when posting code, there is a # sign in the editor that gives you a code block. Place your code inside of these to make it display in a more readable manner.

    -Lee
     
  6. phanfave thread starter macrumors newbie

    Joined:
    Jul 10, 2008
    #6
    Thanks for the suggestions. I think the book is Pre Obj 2.0 so that's why he's having us use Object and not NSObject. I made the change and still have problems. Here is my code now:
    Code:
    #import <objc/Object.h>
    
    @interface Pointxy: NSObject
    {
    	int x;
    	int y;
    }
    
    -(void) setX: (int) xVal;
    -(void) setY: (int) yVal;
    -(void) setX: (int) xVal andY: (int) yVal;
    -(int) x;
    -(int) y;
    @end
    
    #import "Pointxy.h"
    @implementation Pointxy;
    
    -(void) setX: (int) xVal
    {
    	x = xVal;
    }
    
    -(void) setY: (int) yVal
    {
    	y = yVal;
    }
    
    -(void) setX: (int) xVal andY: (int) yVal
    {
    	x = xVal;
    	y = yVal;
    }
    
    -(int) x
    {
    	return x;
    }
    
    -(int) y
    {
    	return y;
    }
    
    @end
    
    
    
    #import <objc/Object.h>
    #import "Pointxy.h"
    
    @interface Rectangle: NSObject
    {
    	int width;
    	int height;
    	Pointxy *origin;
    }
    
    -(void) setWidth: (int) w;
    -(void) setHeigh: (int) h;
    -(void) setWidth: (int) andHeight: (int) h;
    -(void) setOrigin: (Pointxy *) pt;
    -(Pointxy *) origin;
    -(int) width;
    -(int) height;
    -(int) area;
    -(int) perimeter;
    @end	
    
    #import "Rectangle.h"
    
    @implementation Rectangle;
    
    -(void)	setWidth:	(int) w
    {
    	width = w;
    }
    
    -(void) setHeight:	(int) h
    {
    	height = h;
    }
    
    -(void) setWidth: (int) w andHeight: (int) h
    {
    	width = w;
    	height = h;
    }
    
    -(int) width
    {
    	return width;
    }
    
    -(int) height
    {
    	return height;
    }
    
    -(int) area
    {
    	return (width * height);
    }
    
    -(int) perimeter
    {
    	return (2 * width + 2 * height);
    }
    
    -(void) setOrigin: (Pointxy *) pt
    {
    	origin = [[Pointxy alloc] init];
    	[origin setX: [pt x] andy: [pt y]];
    	//origin = pt;
    }
    
    -(Pointxy *) origin
    {
    	return origin;
    }
    
    @end
    
    
    #import "Rectangle.h"
    #import "Pointxy.h"
    #import <stdio.h>
    
    int main (int agrc, char *agrv[])
    {
    	Rectangle *myRect = [[Rectangle alloc] init];
    	Pointxy	*myPoint = [[Pointxy alloc] init];
    	
    	[myPoint setX: 100 andY: 200];
    	
    	[myRect setWidth: 5 andHeight: 8];
    	[myRect setOrigin: myPoint];
    	
    	printf ("Rectangle w = %i, h = %i\n",
    		[myRect width], [myRect height]);
    		
    	printf ("Origin at (%i, %i)\n",
    		[[myRect origin] x], [[myRect origin] y]);
    	
    	printf ("Area = %i, Perimeter = %i\n", 
    		[myRect area], [myRect perimeter]);
    	
    	[[myRect origin] free];
    	[myRect free];
    	[myPoint free];
    }
    I have the same errors and the following warnings:
    /Users/Sean/Developer/Objective-C/Rectangle.m:44: warning: 'Pointxy' may not respond to '-setX:andy:'
    /Users/Sean/Developer/Objective-C/Rectangle.m:53: warning: incomplete implementation of class 'Rectangle'
    /Users/Sean/Developer/Objective-C/Rectangle.m:53: warning: method definition for '-setWidth::' not found
    /Users/Sean/Developer/Objective-C/Rectangle.m:53: warning: method definition for '-setHeigh:' not found
    /Users/Sean/Developer/Objective-C/Program 8.4.m:12: warning: 'Rectangle' may not respond to '-setWidth:andHeight:'
    /Users/Sean/Developer/Objective-C/Program 8.4.m:25: warning: 'Rectangle' may not respond to '-free'
    /Users/Sean/Developer/Objective-C/Program 8.4.m:26: warning: 'Pointxy' may not respond to '-free'


    And here are the error messages:
    2008-08-06 11:09:30.685 Objective-C[4756:10b] *** _NSAutoreleaseNoPool(): Object 0x5c09c40 of class NSCFString autoreleased with no pool in place - just leaking
    Stack: (0x1f37cdf 0x1e44562 0x6201f1 0x62025d 0x6202b1 0x61e94c 0x61ea12)
    2008-08-06 11:09:30.687 Objective-C[4756:10b] *** _NSAutoreleaseNoPool(): Object 0x5c0b920 of class NSCFString autoreleased with no pool in place - just leaking
    Stack: (0x1f37cdf 0x1e44562 0x1e4f9ba 0x62027d 0x6202b1 0x61e94c 0x61ea12)
    2008-08-06 11:09:30.688 Objective-C[4756:10b] *** -[Pointxy setX:andy:]: unrecognized selector sent to instance 0x5c09740
    2008-08-06 11:09:30.688 Objective-C[4756:10b] *** _NSAutoreleaseNoPool(): Object 0x5c0af20 of class NSCFString autoreleased with no pool in place - just leaking
    Stack: (0x1f37cdf 0x1e44562 0x6201f1 0x62025d 0x6202f1 0x61e94c 0x61ea12)
    2008-08-06 11:09:30.689 Objective-C[4756:10b] *** _NSAutoreleaseNoPool(): Object 0x5c0bc90 of class NSCFString autoreleased with no pool in place - just leaking
    Stack: (0x1f37cdf 0x1e44562 0x1e4f9ba 0x62027d 0x6202f1 0x61e94c 0x61ea12)
    2008-08-06 11:09:30.689 Objective-C[4756:10b] *** _NSAutoreleaseNoPool(): Object 0x5c0bcc0 of class NSCFString autoreleased with no pool in place - just leaking
    Stack: (0x1f37cdf 0x1e44562 0x1e4f9ba 0x620312 0x61e94c 0x61ea12)
    2008-08-06 11:09:30.692 Objective-C[4756:10b] *** _NSAutoreleaseNoPool(): Object 0x5c097f0 of class NSException autoreleased with no pool in place - just leaking
    Stack: (0x1f37cdf 0x1e44562 0x620342 0x61e94c 0x61ea12)
    2008-08-06 11:09:30.693 Objective-C[4756:10b] *** _NSAutoreleaseNoPool(): Object 0x5c0b3d0 of class _NSCallStackArray autoreleased with no pool in place - just leaking
    Stack: (0x1f37cdf 0x1e44562 0x1e9e3e8 0x61914b 0x3e50fb 0x62034a 0x61e94c 0x61ea12)
    2008-08-06 11:09:30.693 Objective-C[4756:10b] *** _NSAutoreleaseNoPool(): Object 0x5c0c150 of class NSCFString autoreleased with no pool in place - just leaking
    Stack: (0x1f37cdf 0x1e44562 0x1e4f9ba 0x6190ce 0x3e50fb 0x62034a 0x61e94c 0x61ea12)
    2008-08-06 11:09:30.695 Objective-C[4756:10b] *** _NSAutoreleaseNoPool(): Object 0x5c0c050 of class NSCFData autoreleased with no pool in place - just leaking
    Stack: (0x1f37cdf 0x1e44562 0x1e58c35 0x1e58811 0x6190e2 0x3e50fb 0x62034a 0x61e94c 0x61ea12)
    2008-08-06 11:09:30.696 Objective-C[4756:10b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[Pointxy setX:andy:]: unrecognized selector sent to instance 0x5c09740'
    2008-08-06 11:09:30.697 Objective-C[4756:10b] Stack: (
    6394187,
    4083963,
    6423370,
    6416716,
    6416914

    Looks like the creation of the origin instance is causing the problem. I would have thought I'd want to create it this way instead:
    Code:
    
    	Pointxy *origin = [[Pointxy alloc] init];
    	[origin setX: [pt x] andy: [pt y]];
    
    
    since I'd want to create it as a pointer. I can skip this program for now, but it's bugging me that I don't know why this isn't working. More importantly I need to understand how to do this down the road. Any ideas?
     
  7. pjrobertson macrumors 6502a

    Joined:
    Nov 14, 2007
    #7
    Thanks for the heads up. I've been using the Object class, because that's what is in Steve's book. I'll start using NSObject from now on ;)
     
  8. HiRez macrumors 603

    HiRez

    Joined:
    Jan 6, 2004
    Location:
    Western US
    #8
    1. You define a method setX:andY: and then call it as setX:andy:, notice the Y is not capitalized when you call. Cocoa is case sensitive so it will be an error.

    2. setHeight: is misspelled as setHeigh: in your Rectangle.h file.

    3. In Rectangle.h, you're missing the variable name w in the declaration -(void) setWidth: (int) andHeight: (int) h;

    4. You don't seem to be defining a free: method anywhere in those objects, so of course it will tell you the implementation is incomplete. Furthermore, "free" is a C keyword used to deallocate memory, so I would stay away from using it or any other predefined keyword.

    There might be other things wrong too, but try cleaning those up and see what happens. In short, you have a bunch of typos and you should not be using C or Objective-C keywords as variable or class names. When the compiler complains, pay attention to what it says. If it says a method is incomplete, make sre you've defined all the methods in .m that you declared in .h, and that they are spelled and punctuated correctly (you can help yourself here by copying and pasting the method names from .h before you define them in .m).
     
  9. phanfave thread starter macrumors newbie

    Joined:
    Jul 10, 2008
    #9
    Thanks I'm going to give these a try. I think the bigger problem is that Kochan's book is out of date. In one problem he has us naming objects with reserved words. That one took a little while to figure out. I'm giving Cocoa Programing for OS X a try and I think I have just enough background in Obj C now to be dangerous.

    Sean
     
  10. crackpip macrumors regular

    Joined:
    Jul 23, 2002
    #10
    His book is a bit out of date now with Obj-C 2.0, but in the first part of the book, you are using straight obj-c. You are not including Cocoa/Foundation frameworks. These programs would be portable on any machine that has gcc installed. Once you switch to using NSObject as the root class, then you'll need to import the Cocoa/Foundation frameworks. This occurs later in his book. He talks about the switch and then begins dealing with the Cocoa frameworks.

    crackpip
     
  11. phanfave thread starter macrumors newbie

    Joined:
    Jul 10, 2008
    #11
    Thanks for the feedback. My typos were causing the problem. In the meatime I've decided to give Hillegass's book a shot since it's more recent and still teaches Obj C. When Kochan's 2.0 book comes out I plan to get it and work through that book too. Thanks everyone. Sometimes when you're sure you code is right it's tough to see the mistakes.

    Sean
     

Share This Page