我使用了一个标准的、现代的单例类,其中一个单例类持有一个CTFontRef,如下所示:
@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然后在其他地方我调用[[MySingleton sharedinstance] paintingFont]。
但是,此调用返回nil,直到我在paintingFont前插入一个下划线,如下所示:
sharedInstance->_paintingFont =
CTFontCreateWithName(CFSTR("Helvetica"), 80.0, nil); 为什么会这样呢?编译器不应该要求我包含下划线吗?如果不是,那么早期版本的目的是什么?这个下划线是从哪里来的?我从来没有使用下划线声明属性,我只是在调试器窗口中看到这些看似随机插入到变量名中的属性。
发布于 2012-09-28 07:52:32
从Xcode4.4开始,当你声明一个@property时,编译器会自动为你创建一个ivar并@synthesize访问器方法。默认的ivar是带下划线的。
使用->语法,您可以直接访问ivars,而不是属性。因此,在您的sharedInstance方法中,您可以设置自己的ivar (不带下划线)。但是,当您稍后尝试访问它时,您将使用[ ],它将使用自动合成的getter方法来访问您的属性(以及自动生成的带有下划线的ivar )。
您应该使用.表示法而不是->来访问该属性。或者简单地使用自动生成的名为_paintingFont的ivar。
您还可以通过添加以下代码在实现文件中创建一个属性readwrite。这将允许您在实现中使用点语法来设置属性,但仍然将其保留为其他类的只读。
@interface MySingleton ()
@property (readwrite) CTFontRef paintingFont;
@end如果你想要一个不同的ivar,你可以使用@synthesize来覆盖它。在这两种情况下,您都不必再声明一个ivar。
@implementation MySingleton
@synthesize paintingFont;
....
@end发布于 2012-09-28 07:53:38
这是因为在声明属性paintingFont时,Obj编译器会创建一个实例变量_paintingFont。
通常,属性/变量的设置可以通过以下两种方式完成
与您的解决方案中的属性和sharedInstance->_paintingFont = ...
sharedInstance.paintingFont = ...。这将调用生成的方法setPaintingFont,然后将该方法赋值给实例变量。但是,在这种情况下,该属性是只读的,因此方法2不能使用。
https://stackoverflow.com/questions/12631705
复制相似问题