I’m using a standard, modern singleton class with a singleton holding a CTFontRef, like so:
@interface MySingleton : NSObject {
CTFontRef paintingFont;
}
@property (readonly) CTFontRef paintingFont;
@end
@implementation MySingleton
+ (MySingleton*)sharedInstance
{
static dispatch_once_t once;
static MySingleton *sharedInstance;
dispatch_once(&once, ^{
sharedInstance = [[self alloc] init];
//NB
sharedInstance->paintingFont =
CTFontCreateWithName(CFSTR("Helvetica"), 80.0, nil);
});
return sharedInstance;
}
@end
Then elsewhere I call [[MySingleton sharedinstance] paintingFont].
However, this call returns nil until I insert an underscore before paintingFont like so:
sharedInstance->_paintingFont =
CTFontCreateWithName(CFSTR("Helvetica"), 80.0, nil);
Why is this? Shouldn’t the compiler require me to include the underscore? If not what is the purpose of the earlier version? And where did this underscore come in? I never declared the property with an underscore to begin with, I just see these seemingly random insertions of them into variable names in the debugger window.
Since Xcode 4.4, when you declare a
@property, the compiler will automatically create an ivar for you and@synthesizethe accessor methods. The default ivar is one with an underscore.Using the
->syntax you access ivars directly and not the property. So, in yoursharedInstancemethod you set your own ivar (without the underscore). However when you later try to access it, you use the[ ]which will use the automatically synthesized getter method to access your property (and the automatically generated ivar with an underscore).You should use the
.notation instead of the->to access the property. Or simply use the automatically generated ivar called_paintingFont.You can also make a property readwrite in your implementation file by adding the code below. This will allow you to use the dot syntax in your implementation to set the property, but still leave it readonly for other classes.
If you want a different ivar, you can use
@synthesizeto override it. In both cases, you don’t have to declare an ivar anymore.