Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective-C Is it safe to overwrite [NSObject initialize]?

Basically, I have the following code (explained here: Objective-C Constants in Protocol)

// MyProtocol.m
const NSString *MYPROTOCOL_SIZE;
const NSString *MYPROTOCOL_BOUNDS;

@implementation NSObject(initializeConstantVariables)

+(void) initialize {
     if (self == [NSObject class])
     {
         NSString **str = (NSString **)&MYPROTOCOL_SIZE;
         *str = [[MyClass someStringLoadedFromAFile] stringByAppendingString:@"size"];
         str = (NSString **)&MYPROTOCOL_BOUNDS;
         *str = [[MyClass someStringLoadedFromAFile] stringByAppendingString:@"bounds"];
     }
}

@end

I was wondering: Is it safe for me to have a category that overrides the NSObject's +initialize method?

like image 615
Richard J. Ross III Avatar asked Jan 12 '11 12:01

Richard J. Ross III


1 Answers

In short, no, you cannot safely implement +initialize methods in categories on classes. You'll end up replacing an existing implementation, if there is one, and if two categories of one class both implement +initialize, there is no guarantee which will be executed.

+load has more predictable and well-defined behavior, but happens too early to do anything useful because so many things are in an uninitialized state.

Personally, I skip +load or +initialize altogether and use a compiler annotation to cause a function to be executed on load of the underlying binary/dylib. Still, there is very little you can do safely at that time.

__attribute__((constructor))
static void MySuperEarlyInitialization() {...}

You are far better off doing your initialization in response to the application being brought up. NSApplication and UIApplication both offer delegate/notification hooks for injecting a bit of code into the app as it launches.

like image 144
bbum Avatar answered Oct 09 '22 19:10

bbum