Želja Huber
Želja Huber

Reputation: 337

NSDictionary that doesn't change

I want to make myself things easier so I'm creating a dictionary that is used by other function (to reach key by object or object by key) but that dictionary is always static. Is this fine way to do it or I need property or something else?

+ (NSDictionary *)dictionaryWithCategoriesAndStrings
{
    return @{
             kNewsCategoryAll       : @(NewsCategoryAll),
             kNewsCategoryRadio     : @(NewsCategoryRadio),
             kNewsCategoryEconomics : @(NewsCategoryEconomics),
             kNewsCategoryCulture   : @(NewsCategoryCulture),
             kNewsCategorySport     : @(NewsCategorySport),
             kNewsCategoryTravel    : @(NewsCategoryTravel),
             kNewsCategoryMusic     : @(NewsCategoryMusic),
             kNewsCategorySociety   : @(NewsCategorySociety),
             kNewsCategoryHealth    : @(NewsCategoryHealth)
             };
}

So now I always access this same dictionary through function [self dictionaryWithCategoriesAndString];

Note: Those are keys are static strings declared at top and objects are NSNumbers with integer.

Upvotes: 0

Views: 101

Answers (3)

Abizern
Abizern

Reputation: 150675

Rather than exposing the static to the entire class, you could create it within the method, and initialise it only once with gcd:

This is thread safe.

+ (NSDictionary *)dictionaryWithCategoriesAndStrings {
    static NSDictionary *dict;

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        dict = @{
                 kNewsCategoryAll       : @(NewsCategoryAll),
                 kNewsCategoryRadio     : @(NewsCategoryRadio),
                 kNewsCategoryEconomics : @(NewsCategoryEconomics),
                 kNewsCategoryCulture   : @(NewsCategoryCulture),
                 kNewsCategorySport     : @(NewsCategorySport),
                 kNewsCategoryTravel    : @(NewsCategoryTravel),
                 kNewsCategoryMusic     : @(NewsCategoryMusic),
                 kNewsCategorySociety   : @(NewsCategorySociety),
                 kNewsCategoryHealth    : @(NewsCategoryHealth)
                 };
    });

    return dict;
}

Upvotes: 5

aronspring
aronspring

Reputation: 276

You will be creating a new NSDictionary every time you call this method, so you won't really be accessing the same dictionary as it will just be a new identical one each time. You won't be able to make a property either if you're using it statically. Maybe something a little more like this just so you are accessing the same dictionary each time.

To access this in an instance method, you could use [[self class] dictionaryWithCategoriesAndStrings].

static NSDictionary* dict;


+ (NSDictionary *)dictionaryWithCategoriesAndStrings
{
    if(dict == nil)
    {
        dict = @{
         kNewsCategoryAll       : @(NewsCategoryAll),
         kNewsCategoryRadio     : @(NewsCategoryRadio),
         kNewsCategoryEconomics : @(NewsCategoryEconomics),
         kNewsCategoryCulture   : @(NewsCategoryCulture),
         kNewsCategorySport     : @(NewsCategorySport),
         kNewsCategoryTravel    : @(NewsCategoryTravel),
         kNewsCategoryMusic     : @(NewsCategoryMusic),
         kNewsCategorySociety   : @(NewsCategorySociety),
         kNewsCategoryHealth    : @(NewsCategoryHealth)
         };
    }
    return dict;
}

Upvotes: 1

John
John

Reputation: 2660

Almost right. Every time that selector is executed, a new NSDictionary is created. That is bad. It should only be created once, and it should only be created lazily.

@property (strong, nonatomic) NSDictionary *categoryDict;

- (NSDictionary *) categoryDict
{
    if( !_categoryDict)
    { 
       _categoryDict = @{  @"Key" :@"value" , ....};
    }
    return _categoryDict;
}

Now the dictionary is only created once. and you can get to the dictionary using dot notation.

Upvotes: -1

Related Questions