Objects in Methods

Discussion in 'Mac Programming' started by jim93, Aug 10, 2009.

  1. jim93 macrumors newbie

    Joined:
    Jun 27, 2009
    #1
    I am getting errors about passing objects in my methods but im not sure why I am new to objective-C but experienced with C++ and java so I'm not comfortable to the syntax yet.
    complex.h
    Code:
    @interface ComplexN : NSObject {
    	@public
    	double Re;
    	double Im;
    }
    
    - (ComplexN)Multiply:(id)n;
    
    - (ComplexN)init:(double)re complex:(double)im;
    
    
    @end
    
    complex.m
    Code:
    #import "ComplexN.h"
    
    
    @implementation ComplexN
    
    - (ComplexN) init:(double)re complex:(double)im
    {
    	self.Re = re;
    	self.Im = im;
    	return self;
    }
    -(ComplexN)Multiply:(id)n;
    {
    	
    	ComplexN n2 = (ComplexN) n;
    
    	ComplexN t = [[ComplexN alloc] init:((self.Re)*(n2.Re) - (self.Im)*(n2.Im))
    complex:((self.Im)*(n2.Re) + (self.Re)*(n2.Im))];
    	
    	return t;
    }
    
    I cant just pass ComplexN as a parameter in a method I have read, is that correct?
     
  2. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    ComplexN is an object so you should be passing pointers to an instance of it as both parameters and return values. You should not be passing plain, non-pointer instances.

    So, for example, your method signature of

    Code:
    - (ComplexN)Multiply:(id)n;
    
    should become

    Code:
    - (ComplexN *)Multiply:(id)n;
    
    And I'd question the (id) as well. Do you really support multiplying by an arbitrary object? Or only by another ComplexN?
     
  3. jim93 thread starter macrumors newbie

    Joined:
    Jun 27, 2009
    #3
    Code:
    - (ComplexN *)Multiply:(id)n;
    I dont support arbitrary but I thought I couldnt do
    Code:
    - (ComplexN *)Multiply:(ComplexN *)n;
     
  4. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #4
    Sure you can. Why not? It's the correct thing to do.
     
  5. jared_kipe macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #5
    A couple of things just to nit-pick.
    Code:
    - (ComplexN)init:(double)re complex:(double)im; 
    Kinda breaks a few unspoken rules. While your passed variables re and im, are not IDENTICAL to your instance variable names Re and Im they are very similar which makes them hard to read.

    Secondly, a naming convention. When naming init methods, its most common to have a method that looks like this be called...
    Code:
     - (ComplexN *) initWithReal: (double)real andImaginary: (double)imaginary ;
    It is easier to tell what pieces of information you are passing.
    Then you can have an init method that calls this method with default values such as...
    Code:
     - (ComplexN *) init {
         [self initWithReal: 0.0 andImaginary: 0.0 ];
    }


    For various reasons, you should at the very least be calling [super init] in your init methods.

    Also, in your current init methods you call things like self.Im which is not necessary. You own your instance variables, and in these cases they are not objects. And you have not set up @property 's to be able to do this call in the first place. self.Im = x; is the same thing as [self setIm: x];
    But notice you don't have a setIm method to call.





    In your Multiply method, all of your ComplexN n = .... should be ComplexN *n = ....;
    Whenever you are not dealing with a struct or a built in data type like int or float, you are probably dealing with an object, so you need to put the star in.
    Could be simplified to...
    Code:
     
    -(ComplexN *)Multiply: (id)n;
    {
    	
    	ComplexN *n2 = (ComplexN *) n;
    
    	ComplexN *t = [[ComplexN alloc] init:( Re*(n2.Re) - Im*(n2.Im) )
    complex:( Im*(n2.Re) + Re*(n2.Im) ) ];
    	
        // most methods that return new objects like this autorelease them
        // so that the calling functions can retain them without fear of 
        // over-retaining them.  AND if they only need the object for a short
        // time to do a calculation or put them in a string, they can choose
        // not to retain them and they will release and dissapear on their own.
    
           [t autorelease];
    
    	return t;
    }
    
    This method would require
    @property (read-write, nonatomic) double Re;
    @property (read-write, nonatomic) double Im;
    In the header and
    @synthesize Re, Im;
    in the implementation to setup the n2.Re and self.Im kind of things.
     

Share This Page