views:

556

answers:

1

Ok, here goes. I've completed a Cocoa foundation-tool that calculates mean absolute deviation of random integers (Just as a learning project).

I've moved the calculation into a function called "findMeanAbsoluteDeviation()" It accepts a NSMutableArray of NSNumber objects to preform calculations. Anyways. So this works all fine and dandy when I declare it in the same ".m" file as my other code.

#import <Foundation/Foundation.h>

float findMeanAbsoluteDeviation(NSMutableArray * array);

int main (int argc, const char * argv[]) {
    ...generate random integers, execute function...
    meanAbsoluteDeviation = findMeanAbsoluteDeviation(numArray);
}

float findMeanAbsoluteDeviation(NSMutableArray * array) {
    ...mean absolute deviation maths...

}

and it works fine. Now, I would like to move the function to an external file. I created a subclass of NSObject named "mad". I moved the function into my mad "mad.m", I read up and then re-formatted the declaration to look like

-(float)findMeanAbsoluteDeviation:(NSMutableArray *)array {
    ...code...
}

and in my "mad.h" file.

@interface mad : NSObject {

}

    - (float)findMeanAbsoluteDeviation:(NSMutableArray *)array;

@end

seems all awesome. Right? all I have to do is add...

#import "mad.m"

to the top of my "main.m" file and use the function as I would normally. Well, it doesn't seem to compile correctly.

ld: duplicate symbol .objc_class_name_mad in ------standardDeviation.build/Debug/standardDeviation.build/Objects-normal/i386/mad.o and ------standardDeviation.build/Debug/standardDeviation.build/Objects-normal/i386/standardDeviation.o

"------" is omitted for length's sake

Command /Developer/usr/bin/gcc-4.0 failed with error code 1

Any ideas? Thanks for your help!

+3  A: 

You want #import "mad.h", not #import "mad.m" otherwise the class implementation is evaluated twice, hence the error you're seeing.

A few stylistic points:

  • If you're not using an object's instance variables for anything, you typically write a class method (+) not an instance method (-).
  • There's no problem declaring a C function prototype in an Objective-C header file, if a class interface doesn't make sense for what you're doing. See NSGeometry.h for some examples.
  • If you don't mutate an array in a function or method, don't use a mutable array parameter.
  • Consider using standard Cocoa naming conventions for classes, methods and functions.

For example:

@interface MEMeanAbsoluteDeviation : NSObject {
}
+ (float)meanAbsoluteDeviation:(NSArray *)array;

or simply:

float MEMeanAbsoluteDeviation(NSArray *array);
Nicholas Riley
Ok. I'm loving Stack Overflow. Thank you so much. I changed my "#import" statement. I then read (http://www.otierney.net/objective-c.html) up on class methods, I was wondering what the difference was between + and -. Thank you so much. I am eternally grateful :)One more question, can if my function accepts an NSArray, can I pass it a NSMutableArray becuase it is a subclass of NSArray, or should I NSAray *copyArray = [NSArray initWithArray: myMutableArray]; ? I'm pretty sure its the former.
Matt Egan
Yes, if a method or function takes an object of a particular class it can take an object of a subclass as well. If you do need to make a mutable object (array, dictionary, etc.) out of an immutable one or vice versa, the methods to use are "-copy" (mutable => immutable) and "-mutableCopy" (immutable => mutable).
Nicholas Riley