• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag
 

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: class variables
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


References: 
 >class variables (From: "Jim Thomason" <email@hidden>)
 >Re: class variables (From: Ofri Wolfus <email@hidden>)
 >Re: class variables (From: Bob Smith <email@hidden>)
 >Re: class variables (From: Bob Smith <email@hidden>)

  • Prev by Date: Re: Changing the Color of NSProgressIndicator with CGContextSetBlendMode
  • Next by Date: panels, windows, and the 'esc' key
  • Previous by thread: Re: class variables
  • Next by thread: Re: class variables
  • Index(es):
    • Date
    • Thread