Prelude: It pays to understand the difference between precompiler directives and true constants. A #define
just does a text replacement before the compiler builds the code. This works great for numerical constants and typedefs, but is not always the best idea for function or method calls. I'm operating under the assumption that you really want a true constant, meaning that the code to create the search path should only be executed once.
In your MyClass.m file, define the variable and populate it in an +initialize
method like so:
static NSArray *searchPath;
@implementation MyClass
+ (void) initialize {
searchPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES) objectAtIndex: 0] retain];
}
...
@end
The static
modifier makes it visible only within the compilation unit where it is declared. For a simple constant, this is all you need.
If the class has subclasses, +initialize
will be called once for each subclass (by default), so you'll want to check whether searchPath
is nil
before assigning to it, so you don't leak memory. (Or, as Peter Lewis points out, you can check if the class currently being initialized is the MyClass, using either ==
or the -isMemberOfClass:
method.) If the subclasses also need to access the constant directly, you'd need to pre-declare the variable as extern
in MyClass.h file (which the child classes include):
extern NSArray *searchPath;
@interface MyClass : NSObject
...
@end
If you pre-declare the variable as extern, you must remove the static
keyword from the definition to avoid compile errors. This is necessary so the variable can span multiple compilation units. (Ah, the joys of C...)
Note: In Objective-C code, the better way to declare something as extern
is to use OBJC_EXPORT
(a #define
declared in <objc/objc-api.h>
) which is set based on whether or not you're using C++. Just replace "extern" with "OBJC_EXPORT" and you're done.
Edit: I just happened upon a related SO question.