是否可以将Objective-C类的重写getter保持为静态?

时间:2013-12-04 18:12:00

标签: objective-c

我有一些现有的代码,我正在修改另一个开发人员。它们具有声明如下的静态NSString ...

static NSString *myStaticString;

此字符串应在使用前初始化。我想要做的是有一个属性方法覆盖,它将确保设置变量。这是我建议的布局看起来像......

static NSString *myStaticString;

@interface MyClass ()
@property (readonly) NSString   *myProperty;
@end

@implementation MyClass
+(NSString *)myProperty
{
    if (!myStaticString)
      myStaticString = [@"My string value!" retain];

    return myStaticString;
}
@end

我这里的新事物是我从来没有宣称吸气剂是一种静态方法,说实话我不知道这是不是一个好主意。

3 个答案:

答案 0 :(得分:6)

回答这个问题(我解释)“让getter返回指向静态的指针是否可以?”答案是肯定的,确实如此。

这里的问题是,getter是实例方法,并且您已经定义了一个类方法。所以你最终会得到一个令人困惑的组合,你明确定义的类方法碰巧带有自动合成的getter实例方法的相同名称(更糟糕的是,合成的getter实例方法只会返回指向一些自动合成的指针ivar,这显然不是你想要的)。最重要的是,你并没有像你明显认为的那样压倒吸气剂。

正如bbum指出的那样,您可以通过将此显式声明的方法定义为实例方法来轻松解决此问题。通过这样做,你将完全取代吸气剂,完成你可能想要的东西。

就个人而言,由于这里没有任何需要实例方法的东西,我可能倾向于完全退出该属性并让类方法返回指向静态变量引用的字符串的指针。在这种情况下,我建议采用以下两种方法之一:

  1. 如果字符串真的是常量,那么我可能会做类似的事情:

    // MyClass.h
    
    @interface MyClass : NSObject
    
    + (NSString *)someString;
    
    @end
    

    // MyClass.m
    
    #import "MyClass.h"
    
    static NSString * const kSomeInternalConstant = @"my string";
    
    @implementation MyClass
    
    + (NSString *)someString
    {
        return kSomeInternalConstant;
    }
    
    @end
    
  2. 如果字符串是在运行时定义的,但在应用程序运行时没有更改,那么我将MyClass.m替换为:

    // MyClass.m
    
    #import "MyClass.h"
    
    @implementation MyClass
    
    + (NSString *)someString
    {
        static NSString *someInternalString = nil;
    
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            someInternalString = ...  // set it to be whatever you want
        });
    
        return someInternalString;
    }
    
    @end
    
  3. 显然,用更符合逻辑的东西替换这些变量名称,但希望这说明了这个想法。

答案 1 :(得分:4)

如果你正在寻找@property的等级等级,那么答案是“没有这样的东西”。但请记住,@ property只是语法糖,无论如何;它只是创建了适当命名的对象方法。

您仍然可以使用访问静态变量的类方法,这些变量只有略微不同的语法。

这是线程安全的例子:

// Foo.h
@interface Foo {
}

+(NSDictionary*) dictionary;

// Foo.m
+(NSDictionary*) dictionary
{
  static NSDictionary* fooDict = nil;

  static dispatch_once_t oncePredicate;

  dispatch_once(&oncePredicate, ^{
        // create dict
    });

  return fooDict;
}

答案 2 :(得分:2)

您需要它作为实例方法:

-(NSString *)myProperty
{
    if (!myStaticString)
      myStaticString = [@"My string value!" retain];

    return myStaticString;
}

而且,是的,没关系。


retain是奇数;不需要它,不伤害。最好开启ARC并完成它。

•我将静态移动到方法中,或者如果它永远不会改变,只需直接返回@"My string value!"

•这不是一种罕见的模式;此类可能返回默认的静态值,并且子类可能会覆盖以根据需要返回不同的值。

•初始化静态时,请使用dispatch_once。在这种情况下,它无关紧要,因为它是一个静态常量字符串的赋值。但是,与retain一样,最好遵循惯例(即消除retain,使用dispatch_once或直接返回值。)