dispatch_once vs static

时间:2013-04-15 15:10:43

标签: ios objective-c

我正在为我的应用程序编写帮助程序类。辅助类将返回全局可访问的变量。我创建了一个简单的帮助器,如下所示:

@interface MyHelper : NSObject
{

}

+(id) sharedHelper;

+(NSMutableArray *) employers;


+(id) sharedHelper
{
    static MyHelper *sharedHelper = nil;
    static dispatch_once_t onceToken;

    dispatch_once(&onceToken,^{

        sharedHelper = [[self alloc] init];
    });

    return sharedHelper;
}

+(NSMutableArray *) employers
{
    return _employers; 
}

现在我可以访问这样的雇主:

[MyHelper employers]我也可以像[[MyHelper sharedHelper] employers]那样访问它。每种方法的好处是什么,或者它们都是相同的。

2 个答案:

答案 0 :(得分:2)

我认为雇主阵列是你的班级MyHelper的财产。

如果您在没有调用[MyHelper sharedHelper]的情况下致电[MyHelper employees],您可能会得到错误的结果(雇主数组的值是垃圾)。

这里最好的做法是在+(NSMutableArray *)雇主中使用延迟加载,并从+(id)sharedHelper中获取静态变量:

static MyHelper *sharedHelper = nil;
static dispatch_once_t onceToken;

+(id) sharedHelper
{
    dispatch_once(&onceToken,^{

        sharedHelper = [[self alloc] init];
    });

    return sharedHelper;
}

+(NSMutableArray *) employers
{
    if(!sharedHelper)
        [MyHelper sharedHelper]; 

    return _employers; 
}

答案 1 :(得分:0)

employers类方法引用_employers,这可能是您的类的实例变量。你不能这样做。此外,即使你做了一些草率的解决方法,比如全局变量,你也不能保证_employers已被实例化,除非employers类方法也确保调用sharedHelper。 / p>

所以,有几点想法:

  1. 你真的应该有employers的一些类属性(我假设你做了,但为了简洁起见省略了它,但让我们在这里包括它来消除歧义):

    @interface MyHelper : NSObject
    
    @property (nonatomic, strong) NSMutableArray *employers;
    
    @end
    
  2. 我认为您的init方法会初始化此employers对象

    - (id)init
    {
        self = [super init];
        if (self) {
            _employers = [[NSMutableArray alloc] init];
        }
        return self;
    }
    
  3. 您现有的sharedHelper方法完全没问题。

  4. 但是,如果您要使用employers类方法,则应访问employers实例方法:

    + (NSMutableArray *)employers
    {
        return [[MyHelper sharedHelper] employers];
    }
    
  5. 完成所有这些后,您的课程将如下所示:

    @interface MyHelper : NSObject
    
    @property (nonatomic, strong) NSMutableArray *employers;
    
    + (id)sharedHelper;
    + (NSMutableArray *)employers;
    
    @end
    
    @implementation MyHelper
    
    + (id)sharedHelper
    {
        static MyHelper *sharedHelper = nil;
        static dispatch_once_t onceToken;
    
        dispatch_once(&onceToken,^{
            sharedHelper = [[self alloc] init];
        });
    
        return sharedHelper;
    }
    
    - (id)init
    {
        self = [super init];
        if (self) {
            _employers = [[NSMutableArray alloc] init];
        }
        return self;
    }
    
    + (NSMutableArray *)employers
    {
        return [[MyHelper sharedHelper] employers];
    }
    
    @end
    

    这很有效,但话虽如此,作为一种风格问题,当你有一个同名属性的getter方法时,我个人不推荐使用类方法employers。似乎有点混乱。我会删除employers类方法,并坚持使用将为您合成的标准getter方法,结果只是:

    @interface MyHelper : NSObject
    
    @property (nonatomic, strong) NSMutableArray *employers;
    
    + (id)sharedHelper;
    
    @end
    
    @implementation MyHelper
    
    + (id)sharedHelper
    {
        static MyHelper *sharedHelper = nil;
        static dispatch_once_t onceToken;
    
        dispatch_once(&onceToken,^{
            sharedHelper = [[self alloc] init];
        });
    
        return sharedHelper;
    }
    
    - (id)init
    {
        self = [super init];
        if (self) {
            _employers = [[NSMutableArray alloc] init];
        }
        return self;
    }
    
    @end
    

    然后使用此MyHelper类的其他代码可以简单地引用[[MyHelper sharedHelper] employers]