objc

Discussion in 'Mac Programming' started by jamesapp, Apr 4, 2008.

  1. macrumors 6502a

    Joined:
    Mar 7, 2008
    #1
    james-collinss-macbook-pro:prog9 jamescollins$ gcc prog9.2.m -o prog9.2 -l objc
    Undefined symbols:
    ".objc_class_name_Complex", referenced from:
    literal-pointer@__OBJC@__cls_refs@Complex in cciaLwic.o
    ".objc_class_name_Fraction", referenced from:
    literal-pointer@__OBJC@__cls_refs@Fraction in cciaLwic.o
    ld: symbol(s) not found
    collect2: ld returned 1 exit status

    got this error message when i tried to run a program from a book.

    here is my test file which i called prog9.2.m

    Code:
    //illustrate Dynamic Typing and Binding
    
    #import "Fraction.h"
    #import "Complex.h"
    
    int main (int argc, char *argv[])
    {
      id  dataValue;
      Fraction *f1 = [[Fraction alloc] init];
      Complex *c1 = [[Complex alloc] init];
      
      [f1 setTo: 2 over: 5];
      [c1 setReal: 10.0 andImaginary: 2.5];
      
      // first dataValue gets a fraction
      
      dataValue = f1;
      [dataValue print];
      printf ("\n");
      
      //now dataValue gets a complex number
      
      dataValue = c1;
      [dataValue print];
      printf ("\n");
      
      [c1 free];
      [f1 free];
      [dataValue free];
      
      return 0;
    }
    [code]
    
    i think the problem is in Complex.h and Fraction.h so i will include those two files.
    
    first Fraction.h
    
    [code]
    #import <objc/Object.h>
    #import <stdio.h>
    
    // define the fraction class
    
    @interface Fraction : Object
    {
    
    
      int numerator;
      int denominator;
    }
    -(void)  print;
    -(void) setNumerator: (int) n;
    -(void) setDenominator: (int) d;
    -(void) setTo: (int) n over: (int) d;
    -(void) reduce;
    -(int)  numerator;
    -(int)  denominator;
    -(double) convertToNum;
    
    @end
    [code]
    
    and then Complex.h
    
    [code]
    //Interface file for Complex class
    
    #import <objc/Object.h>
    
    @interface Complex: Object
    {
      double real;
      double imaginary;
      double compResult;
    }
    
    -(void) print;
    -(void) setReal: (double) a;
    -(void) setImaginary: (double) b;
    -(void) setReal: (double) a andImaginary: (double) b;
    -(double) real;
    -(double) imaginary;
    -(double) compResult;
    -(Complex *) add: (Complex *) f;
    @end
    [code]
    
    any help would be appreciated.
     
  2. macrumors G5

    gnasher729

    Joined:
    Nov 25, 2005
    #2
    Where are Fraction.m and Complex.m ?
     
  3. thread starter macrumors 6502a

    Joined:
    Mar 7, 2008
    #3
    here is complex.m

    // Implementation file for Complex class

    #import "Complex.h"
    #import <stdio.h>

    @implementation Complex;
    -(void) print
    {
    printf (" %g + %gi ", real, imaginary);
    }


    -(void) setReal: (double) a
    {
    real = a;
    }

    -(void) setImaginary: (double) b
    {
    imaginary = b;
    }

    -(void) setReal: (double) a andImaginary: (double) b
    {
    real = a;
    imaginary = b;
    }

    -(double) real
    {
    return real;
    }

    -(double) imaginary
    {
    return imaginary;
    }

    -(Complex *) add: (Complex *) f
    {
    Complex *result = [[Complex alloc] init];

    [result setReal: real + [f real]
    andImaginary: imaginary + [f imaginary]];

    return result;
    }
    @end

    and fraction.m

    #import "Fraction.h"
    #import <stdio.h>

    @implementation Fraction;

    -(Fraction *) initWith: (int) n: (int) d
    {
    self = [super init];

    if (self)
    [self setTo: n over: d];
    return self;
    }

    // add a fraction to the receiver

    -(Fraction *) add: (Fraction *) f
    {
    // to add two fractions
    // a/b + c/d = ((a*d) + (b*c)) / (b * d)

    // result will store the result of the addition
    Fraction *result = [[Fraction alloc] init];
    int resultNum, resultDenom;

    resultNum = (numerator * [f denominator]) +
    (denominator * [f numerator]);
    resultDenom = denominator * [f denominator];

    [result setTo: resultNum over: resultDenom];
    [result reduce];

    return result;
    }

    -(void) reduce
    {
    int u = numerator;
    int v = denominator;
    int temp;
    while (v != 0) {
    temp = u % v;
    u = v;
    v = temp;
    }

    numerator /= u;
    denominator /= u;
    }
    -(void) print
    {
    printf (" %i/%i ", numerator, denominator);
    }

    -(void) setNumerator: (int) n
    {
    numerator = n;
    }

    -(void) setDenominator: (int) d
    {
    denominator = d;
    }

    -(int) numerator
    {
    return numerator;
    }

    -(int) denominator
    {
    return denominator;
    }

    -(double) convertToNum
    {
    if (denominator != 0)
    return (double) numerator / denominator;
    else
    return 1.0;
    }


    -(void) setTo: (int) n over: (int) d
    {
    numerator = n;
    denominator = d;
    }
    @end
     
  4. macrumors G4

    Eraserhead

    Joined:
    Nov 3, 2005
    Location:
    UK
    #4
    I'm not sure what your problem is, but I do have some general tips, see whether they help.

    In complex.m
    #Use NSLog not printf so you don't have to import stdio.h.

    #In the add method as you are returning a reference you should create a new complex number to store the result, as you do in Fraction.m

    In fraction.m you need to have a name for the second part of the init method.

    You also need to have a general init method that for complex sets both values to 0 and for fraction sets the numerator (the top one) to 0 and the denominator to 1.

    You also should use [c1 release] not [c1 free] to free the memory.
     
  5. macrumors 65816

    Sbrocket

    Joined:
    Jun 3, 2007
    Location:
    /dev/null
    #5
    Do you think you could wrap your code in
    Code:
     tags so its a bit easier to read? Just edit the posts above.
    
    Ok, your code has other problems that people above mentioned a few of...but you're not compiling correctly. You didn't compile your other files, so you're getting errors about missing symbols.
    
    [code]
    gcc -c Fraction.m Complex.m prog.m && gcc -o prog Fraction.o Complex.o prog.o -lobjc
    
    In any case, running the compiled program results in a segfault so you have some memory management things to address.

    @Eraserhead: He can't use -[NSObject release] since his classes are subclassed from Object rather than NSObject and he hasn't imported and linked in Foundation. I would do that, personally (subclass from NSObject not Object), import <Foundation/Foundation.h> and link in the framework like so:

    Code:
    gcc -c Fraction.m Complex.m prog.m && gcc -o prog -framework Foundation Fraction.o Complex.o prog.o -lobjc
    
    You know...if you used Xcode you probably wouldn't have to deal with the nitty gritty compiling and such. :D

    EDIT52: Oh, and you're getting a segmentation fault because of this: (Well, on yours its -[Object free] instead of -[NSObject release], but you should change that like I said)

    Code:
    dataValue = c1;
    ...
    [c1 release];
    [f1 release];
    [dataValue release];
    
    You're releasing the object that c1 (and dataValue) points to twice, so you get a segfault. Take out the [dataValue release].

    EDIT53: Just to show you it does in fact work...

    Code:
    [~][19:29:14 bryan]$ gcc -c Fraction.m Complex.m prog.m && gcc -o prog -framework Foundation Fraction.o Complex.o prog.o -lobjc
    Complex.m:45: warning: incomplete implementation of class ‘Complex’
    Complex.m:45: warning: method definition for ‘-compResult’ not found
    [~][19:39:09 bryan]$ ./prog
     2/5 
     10 + 2.5i 
    
    Man, this turned into a long post.
     
  6. macrumors G4

    Eraserhead

    Joined:
    Nov 3, 2005
    Location:
    UK
    #6
    Ah, I've always used Xcode for Cocoa stuff so I've never had to worry about that stuff...
     
  7. macrumors 65816

    Sbrocket

    Joined:
    Jun 3, 2007
    Location:
    /dev/null
    #7
    Hehe, so do I. I just figured out this stuff as I was typing the post.
     
  8. thread starter macrumors 6502a

    Joined:
    Mar 7, 2008
    #8
    i believe one of my problems was when i compiled the program i used .h files instead of .m.
    i still don't understand the segmentation fault error, didn't i free the variables?
     
  9. macrumors 65816

    Sbrocket

    Joined:
    Jun 3, 2007
    Location:
    /dev/null
    #9
    You did...the problem is you over-freed the variables. That's what caused the segmentation fault. If you didn't release anything, it would just cause a leak (or in this case do nothing since the program just ends and the memory used by the program is freed anyway).

    Say I do this:
    Code:
    Complex *aComplex = [[Complex alloc] init];
    Complex *bComplex;
    
    bComplex = aComplex;
    
    [bComplex free];       // or [bComplex release];
    
    That code is correct. However if I added one more line...
    Code:
    [aComplex free];
    ...then a segfault occurs since you're attempting to free/release the object that both aComplex and bComplex point to when its already been deallocated.

    Have you got the compiling stuff down? You don't need the one with "-framework Foundation" if you're going to stay with subclasses of Object, I'm just used to using Foundation.
     
  10. macrumors regular

    Joined:
    Apr 1, 2006
    Location:
    California
    #10
    NSObject vs. Object

    All you Xcode advocates will be happy to know that I'm going to get rid of all the Object.h, gcc, and printf stuff and work directly with NSObject, Xcode, and NSLog in the second edition of my book. The reason for the original approach was due to my hope that Objective-C would gain popularity on more than just the Mac OS X platform. Well, guess what? It hasn't happened! Therefore, I've decided that the second edition will avoid the switch from Object to NSObject and be more Mac-centric right from the start. Of course, I'm also revising it to address Objective C 2.0 (the biggest change will be the approach to memory management in light of the garbage collector). And for those of you who didn't like my description of the bitwise operators (admittedly there's a few of you out there), I promise to do a better job the second time around.

    Suggestions for the 2nd edition are welcome.

    Cheers,

    Steve Kochan
     
  11. macrumors 65816

    Sbrocket

    Joined:
    Jun 3, 2007
    Location:
    /dev/null
    #11
    Not to get too far off-topic, but while you're here...

    I would be careful about leaning too far into the garbage collection side of Objective-C 2.0. Proper memory management is still an important thing for budding programmers to learn properly unless they're only going to be developing for GC-enabled environments (of which the iPhone is not). Fundamentals can't hurt any, just expand the reader's breadth of knowledge.

    Oh and implementing user interfaces in code (and not relying on Interface Builder too much, though it is an invaluable tool when it works for your project) is a good skill for new Cocoa developers, too. You could have this in there already, I dunno, I haven't picked up any books yet personally since I'm waiting for them to get updated (and hopefully find one with some Cocoa Touch stuff in it).
     
  12. macrumors 68020

    Krevnik

    Joined:
    Sep 8, 2003
    #12
    While I agree it is fairly useful to understand how UI components fit together, it is also possible to take this too far. Merging your controllers and views are all to easy to do (I have issues with it myself on custom controls) and makes code harder to maintain. Interface Builder helps enforce this separation of view and application behavior.

    But, it is still very important to understand how the UI bits connect to each other, as it will help when you get around to writing custom controls (which unless you are on the iPhone, will happen more often than you think).
     
  13. thread starter macrumors 6502a

    Joined:
    Mar 7, 2008
    #13
    took out [datavalue free]
    program worked.

    i have a question about posting code.
    i have been placing
    Code:
     at the beginning and end of my program files.
    what is the proper way to post code?
     
  14. macrumors 65816

    Sbrocket

    Joined:
    Jun 3, 2007
    Location:
    /dev/null
    #14
     

Share This Page