PDA

View Full Version : objective c public constants and enums?




Chirone
Mar 2, 2009, 08:55 PM
back in the old days you would be able to go myClass.MY_CONSTANT and that would return to you the value of MY_CONSTANT which is specific to myClass

in objective c if i go #define MY_CONSTANT i can't access it outside of the class
i can't put anything in the @interface part because it just throws compile errors

const int MY_CONSTANT 0;
static const int MY_CONSTANT = 0;
static int MY_CONSTANT = 0;

and everything else i can think of throws an error

is it possible in objective c to just go myClass.MY_CONSTANT? and if so then how am i meant to declare MY_CONSTANT in myClass? i don't want to have to make an instance of myClass just to access it because that's just silly when its the same throughout all classes


also, on the issue of enums
typedef enum {
CONSTANT_ZERO = 0,
CONSTANT_ONE = 1
} someName
in the class i can just type CONSTANT_ZERO and it gives me the value (which is understandable)
but the someName is pretty much redundant as its never used in the class and no one outside the class can use it as well.
so there isn't really a point to enums in obj c is there?



lee1210
Mar 2, 2009, 09:22 PM
Stick the enum definition in a .h file, include it in source files where you need it, and use someName to declare new instances of the enum to assign the possible values.

As for the . situation, i abhor it. Use accessors and mutators. You can set up a static variable in your classes .h file, then make class level methods for accessing it, setting it, etc. It's not the same as a true class level variable, but it works.

-Lee

Chirone
Mar 2, 2009, 09:30 PM
including the header file might have been what went wrong...

but anyway, what i want to do is have an array of rectangles and make it easy on the coder to tell which rectangle they are getting and also to make it easier if there are changes in the future

so instead of going
[myArray objectAtIndex: 0]
you'd go
[myArray objectAtIndex: ENUM_NAME]
and if the index of the NSRect changes then you just need to change the ENUM_NAME

sure you could go
[myArray objectAtIndex: [myClass getName]]
but that means that you've lost memory because for every instance of myClass you've just got the same value in multiple parts of your memory and they are all used for the same thing.

yeah i know 'memory is cheap just buy more' etc etc, but why should that stop us from not taking up lots of memory?


i was going to change to an NSMutableDictionary because i thought it would actually work
but it turns out i can't stick NSRect objects into one....

my bad, i can't add NSRect to NSMutableArray either....
i guess this means i have to make four arrays or dictionaries for all four components....

jumped way too soon for that statement

i found how to add a rect to dictionary

[<NSDictionary> setValue: [NSValue valueWithRect: <NSRect>] forKey: <id>]
all good.... i think


the whole constant and enum problem still exists
i included the header file in the other class and i still had no access to such things

to clarify myHeader.h has the #define MY_CONSTANT 0
and the typedef enum { MY_ENUM } someName
and myClass.mm implements myHeader.h and can access them ok (except for someName, it refuses to recognise it as anything when called, i can access MY_ENUM though)
and myOtherClass.mm is wanting to know what those constants are because it needs to get particular items out from the array that myClass has.

lee1210
Mar 3, 2009, 10:37 AM
I'm not at a Mac, so i can't easily test example code, and i don't want to lead you astray. This page details using a static variable and an accessor to simulate a class variable:
http://www.otierney.net/objective-c.html#class

As for the enum... i really am not sure what you're trying to accomplish, using enum'd values as indicies into an array isn't totally straight forward to me, but in any event, i think you might want to do something like:
enum rectPositions {FIRST = 0, SECOND = 1, THIRD = 2};
typedef enum rectPositions rPos;
in a header, then in code:
rPos x = FIRST;
rPos y = SECOND;

I can look into more specific examples and usage when i have access to a mac, but you may want to explain what problem you're trying to solve, because my head was spinning after that last post.

-Lee

Chirone
Mar 3, 2009, 03:04 PM
thanks for the reply and help lee!

that simulation of a class variable is helpful. it's strange how i missed it before. must of been because at the time i first read that page i was expecting obj c to have public static variables and thought nothing of that

ok, lets see if i can explain the enums again :)

a header with the enum

@interface myClass : NSObject {
@private
NSMutableArray* myArray;
}
-(NSRect) getRectangleAt: (int) index;
typedef myEnum {
ENUM_ZERO = 0,
ENUM_ONE = 1
} myEnums;
@end

the class that implements this header:
here the init method initialises the array and the other method returns the element at the index given (i'm omitting checks to see if the index is in range etc)

#import "myClass.h"
@implementation myClass {
-(myClass*) init {
self = [super init];
if (self) {
NSRect myRect, myOtherRect;
myArray = [[NSMutableArray alloc] init];
[myArray addObject: [NSValue valueWithRect: myRect]];
[myArray addObject: [NSValue valueWithRect: myOtherRect]];
}
return self;
}
-(NSRect) getRectangleAt: (int) index {
return [myArray objectAtIndex: index];
}
@end


the header for a outsider class that wants to use that enum

@implementation myOtherClass : NSObject {
}
-(void)doStuff;

the implementation of that header
the do stuff method is trying to assign a rectangle a rectangle from the array of rectangles in myClass

#import "myOtherClass.h"
@implementation myOtherClass {
}
-(void)doStuff {
myClass* aClass = [[myClass alloc] init];
NSRect thisRect = [myClass getRectangleAt: aClass.myEnums.ENUM_ZERO];
}

the line aClass.myEnums.ENUM_ZERO is going to throw an error. how can i get access to that enum that's in the class?

In future when more rectangles come more enums can be introduced to find them in the array.

i hope this makes more sense :confused:

lee1210
Mar 3, 2009, 03:28 PM
I think the expectation of needing to dot things is what is causing consternation here. Enums aren't as advanced in C/Objective-C as you are making them. Change:
aClass.myEnums.ENUM_ZERO
to
ENUM_ZERO

and pull the enum definition out of your @interface, and I think you should be in business.

-Lee

Edit: I still don't know why you are using an enum'd value to index an array. Why not just have an NS(Mutable)Dictionary, instead? Perhaps if you want compiler enforced access, you could still use an enum as the argument to a method that changes the value into a usable key to the dictionary, etc. The enum-as-index thing seems to really be complicating things. Why are your rectangles in an array and not just named members of your class?

Chirone
Mar 3, 2009, 03:32 PM
oh right i get it

what you said makes sense considering enums are really just a whole lot of #define....
i used the static method that you pointed out to me before to gain access to such constants and it works quite well.

thanks heaps Lee :)