Objective C static class variables

I am new to Objective C and am reading a book called "Visual Quickstart Guide: Objective-C" by Steven Holzner, Peachpit Press

In Chapter 6: Object Oriented Programming, there is a section called Using Class Variables where he writes:

You can create class variables for use with your classes, but there’s a hitch: every object of that class shares the same variable, so if one object changes a class variable, that variable is changed for all objects. You create class variables with the static keyword. Class variables are often useful: for example, you can use a class variable to keep track of the number of objects of a particular class created in a program. You’ll do that in this task.

And says to enter the following code:

#import <stdio.h>
#import <Foundation/NSObject.h>
@interface TheClass: NSObject
static int count; //error: cannot declare variable inside @interface or @protocol
+(int) getCount;
@end
...

This code gives me an error in Xcode 4:

Cannot declare variable inside @interface or @protocol

Is the book wrong or am I doing something wrong?


You declare the static variable in the implementation file (.m file). This should work:

// TheClass.h
@interface TheClass : NSObject
+ (int)count;
@end

// TheClass.m
static int theCount = 0;

@implementation TheClass
+ (int) count { return theCount; }
@end

It's not a class variable per se; Objective-C has no notion of a class variable. However, coupled with the class method for retrieving this variable, it functions similarly to a class variable. However, it's really just a C static variable that's accessible by the class's implementation.


I’ve seen one Visual Quickstart Guide about Unix and it sucked big time. This one does not seem to be much better, at least from the sample. The correct way to create a class variable in Objective-C looks like this:

// Counted.h
@interface Counted : NSObject

+ (NSUInteger) numberOfInstances;

@end

// Counted.m
#import "Counted.h"

static NSUInteger instances = 0;

@implementation Counted

- (id) init {
    …
    instances++;
    …
}

- (void) dealloc {
    instances--;
}

+ (NSUInteger) numberOfInstances {
    return instances;
}

@end

This is in fact a static variable, not a true class variable. But you should not worry about class variables too much anyway, they’re usually a sign that you’re doing something wrong. (I’m oversimplifying a bit, but not much.)

If you’re looking for a decent Objective-C book, read the one by Apple. It’s free and it’s a good reading.