Re: class variables
Re: class variables
- Subject: Re: class variables
- From: Bob Smith <email@hidden>
- Date: Tue, 20 Feb 2007 17:18:03 -0800
Well this was bugging me because the documentation is so clear about
it, so I tested the following code (pasted in directly from Xcode):
#import <Foundation/Foundation.h>
@interface DataClass : NSObject
+ (void)initialize;
+ (int)foo;
@end
@interface DataSubClass : DataClass
- (int)foo;
@end
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSLog(@"sending message to class");
int result = [DataClass foo];
NSLog(@"result = %d", result);
NSLog(@"instantiating subclass");
DataSubClass *it = [DataSubClass new];
NSLog(@"sending message to subclass instance");
result = [it foo];
NSLog(@"result = %d", result);
[pool release];
return 0;
}
@implementation DataClass
static int Foo = 0;
+ (void)initialize {
NSLog(@"in initialize method");
Foo++;
}
+ (int)foo {
NSLog(@"in class accessor");
return(Foo);
}
@end
@implementation DataSubClass
- (int)foo {
NSLog(@"in instance accessor");
return([DataClass foo]);
}
@end
[Session started at 2007-02-20 17:08:53 -0800.]
2007-02-20 17:08:53.588 initialize_test[1631] sending message to class
2007-02-20 17:08:53.589 initialize_test[1631] in initialize method
2007-02-20 17:08:53.589 initialize_test[1631] in class accessor
2007-02-20 17:08:53.590 initialize_test[1631] result = 1
2007-02-20 17:08:53.590 initialize_test[1631] instantiating subclass
2007-02-20 17:08:53.590 initialize_test[1631] in initialize method
2007-02-20 17:08:53.590 initialize_test[1631] sending message to
subclass instance
2007-02-20 17:08:53.590 initialize_test[1631] in instance accessor
2007-02-20 17:08:53.590 initialize_test[1631] in class accessor
2007-02-20 17:08:53.590 initialize_test[1631] result = 2
initialize_test has exited with status 0.
So I was right about multiple calls to +initialize, but wrong about
it not being called before class methods. I must have had some other
bug causing what happened to me last week. Huh.
Bob S.
On Feb 20, 2007, at 3:18 PM, Bob Smith wrote:
Hmmm, not to question the docs or anything, but experience doesn't
agree. I had this issue in the front of my mind because I just got
bit by it last week, in a situation where I had a class
implementation which contained only class methods and static data,
and was never instantiated. I was tearing my hair for a few hours
before I finally threw an NSLog in +initialize and found it was
never being called. What the documentation says is true about
+initialize being called before the first method call to an
_instance_ of a class; but it's clear that +initialize is not
guaranteed to have been called before a _class_ method is called.
It would appear that +initialize is being called somewhere in the
instance initializer chain, i.e. in NSObject's -init.
Also if you read all the way through that documentation section, at
the end it warns that a class' +initialize can be called more than
once. If you have a superclass which implements +initialize and a
subclass of it which does not override, the superclass' +initialize
will be called both when the superclass is first instantiated, then
again the first time the subclass is instantiated. So if you are
using +initialize to allocate static data, you should guard against
allocating more than once (good practice in any case when
allocating static data).
Bob S.
On Feb 20, 2007, at 1:55 PM, Ofri Wolfus wrote:
+initialize is invoked by the runtime before the first message to
the class is dispatched and not before it is instantiated, so the
first example is fine although both ways are valid. See http://
developer.apple.com/documentation/Cocoa/Reference/Foundation/
Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/
clm/NSObject/initialize
The advantage of +initialize is that it is guaranteed to be
invoked exactly once so if your class should be thread safe,
+initialize may be easier to use.
- Ofri
- - - - - - - - - - - - - - - - - - -
http://www.dpompa.com
- - - - - - - - - - - - - - - - - - -
On 20/02/2007, at 23:45, Bob Smith wrote:
Remember that +initialize is not invoked until the first time a
class is instantiated; so the example will work only if the
methods are in a class that is always instantiated before you
need to access the array. If you need the data in instances of
other classes, or you want to have a separate class just for your
static data, it's safer to have the accessor create the array on
demand:
@implementation DataClass
static NSArray *myArray = nil;
+ (NSArray *)myArray {
if (!myArray) {
myArray = [... retain];
}
return(myArray);
}
@end
Bob S.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden