2013-04-15 3 views
2

В настоящее время я пишу вспомогательный класс для своего приложения. Класс-помощник вернет глобально доступные переменные. Я создал простой помощник, как показано ниже:dispatch_once vs static

@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

Я полагаю, что массив работодателей является собственностью вашего класса MyHelper.

Если вы позвоните [MyHelper работодателям] без вызова [MyHelper sharedHelper], вы можете получить неверный результат (значение массива работодателей - мусор).

Может быть, лучшая практика здесь, чтобы использовать отложенную загрузку в + (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; 
} 
+0

В вашем методе класса «работодатели» вы пытаетесь напрямую получить доступ к ivar '_employers'. Я не думаю, что вы можете сделать это из метода класса. Или они предполагают, что он делает '_employers' глобальным? – Rob

+1

Вы правы. Я попытался как можно меньше изменить версию, содержащуюся в вопросе, поэтому я предполагаю, что _employers - это своего рода статическая или глобальная переменная. –

0

Вам employers метод класса ссылается _employers, который предположительно, переменную экземпляра для вашего класса. Вы не можете сделать это. Более того, даже если вы сделали небрежное обходное решение, например глобальную переменную, у вас нет гарантий, что _employers был создан, если метод класса employers также не гарантирует, что вызывается sharedHelper.

Таким образом, пара мыслей:

  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]; 
    } 
    

Проделав все это, ваш класс будет выглядеть следующим образом:

Это работает, но, говоря о том, что в качестве стиля я лично не рекомендовал бы метод класса, employers, когда у вас есть метод getter для свойства с тем же именем. Кажется немного запутанным. Я бы иссечь этот метод employers класса, и придерживаться стандартного метода геттера, который будет синтезированным для вас, в результате чего только:

@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] себя.