Question

This has been bugging me for a long time, and I have tried to look it up many times.

When I first began learning Objective-C, I remember looking into class variables. I saw many threads on stack overflow and elsewhere that basically said, "Objective-C doesn't support class variables like C does, but there are some workarounds."

Reading this made me shy away from using class variables, especially because I have read hundreds of times that global variables tarnish the elegance of OOP.

So I have a very open ended, opinionated, and conversational question: Should I use class variables in objective C? Also, am I doing it right?

Here is my situation: I am making an app, and I set up a touch handling class to deal with all the input received from screen touches. The data is pretty useful, and I would like every single sprite to have access to it.

Since every object is a subclass of my GameObject class, I figure I just make a class variable, done like so:

header for GameObject class:

+(SSTouchHandler *)touchHandler;
+(void)setHandler:(SSTouchHandler *)handler;

implementation for GameObject class:

static SSTouchHandler *touchHandler = nil;

+(SSTouchHandler *)touchHandler
{
    if (touchHandler)
        return touchHandler;
    else
        return nil;
}

+(void)setHandler:(SSTouchHandler *)handler
{
    touchHandler = handler;
}

Now, this works. This works beautifully.

I can refer to my handler with [GameObject touchHandler] from every place I need.

This is all I could ever want and more.

But should I use this method? Am I dirtying the beauty that is object oriented programming?

Is there a way I should touch up this process to make it work optimally?

Thanks for any and all input, I probably rambled a bit, I just don't want to proceed with a faulty game structure.

Was it helpful?

Solution

I saw many threads on stack overflow and elsewhere that basically said, "Objective-C doesn't support class variables like C does, but there are some workarounds.

"Class variables" make no sense in the context of C since C is not object oriented.

So I have a very open ended, opinionated, and conversational question: Should I use class variables in objective C? Also, am I doing it right?

This is more of a general OOP question than anything specific to Objective-C. The answer tends to be pretty subjective, but in general I'd say to avoid them unless you're trying to set a property of some sort that affects all instances of a class.

Here is my situation: I am making an app, and I set up a touch handling class to deal with all the input received from screen touches. The data is pretty useful, and I would like every single sprite to have access to it.

It sounds to me like a better design pattern for this would be to pass the SSTouchHandler instance as a parameter to the initializer of the sprite objects that use it. e.g.:

@interface GameObject : NSObject
- (id)initWithTouchHandler:(SSTouchHandler *)handler;
@end

Now, if you really want to use the same instance of SSTouchHandler for every GameObject, you have two options:

1) The controller/factory that creates the GameObject objects should create and keep a reference to a single instance of SSTouchHandler, and then initialize any new GameObject instances with it. For example:

@interface GameObjectController : NSObject
@property (nonatomic, strong, readonly) SSTouchHandler *touchHandler;
- (GameObject *)newGameObject;
@end

@implementation

- (id)init
{
    if ((self = [super init])) {
        _touchHandler = [[SSTouchHandler alloc] init];
    }
    return self;
}

- (GameObject *)newGameObject
{
    return [[GameObject alloc] initWithTouchHandler:self.touchHandler];
}

@end

2) You could make SSTouchHandler a shared singleton and call methods on the shared instance directly from the implementation of GameObject. However, shared singletons are discouraged in OOP because they hide dependencies and make it difficult to unit test code that depends on them. You shouldn't go down this route unless you deem it absolutely necessary.

implementation for GameObject class: ...

If you decide that the patterns above aren't suitable for your use case (and that sometimes does happen), yes that is essentially how you would implement class properties in Objective-C. One thing:

if (touchHandler)
        return touchHandler;
    else
        return nil;

This is not necessary, you can just return touchHandler since it will be nil anyways if not set.

OTHER TIPS

If it works, you're done. I think there are some improvements, though. First, you might like to use an instance var here: it's not more complicated, but it allows some flexibility in the future (e.g. if you want to make two views side by side). Also, using a bare pointer is not so good; the class here does not own the pointer, and it can be left dangling! Defining the touchHandler as a property (also an instance var) takes care of that problem.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top