Search code examples
objective-cgrand-central-dispatchstatic-variablesclass-method

Aren't static variables in an Objective-C class method shared across all subclasses?


I'm really perplexed. I have a class A with a class method that returns a shared cache instance:

+ (NSCache *)itemCache {
    static NSCache *itemCache;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        itemCache = [[NSCache alloc] init];
    });
    return itemCache;
}

I also have a subclass B of class A.

Whenever I call [A itemCache] I get one instance of the cache. Whenever I call [B itemCache] I get a different instance of the cache.

Are static variables unique to the particular class the method is called on? I thought they were shared across all subclasses.

Edit Nevermind, there was something else going. The world does indeed work like I thought it did. I have an app target and a test target. Class A was being included in both targets. Class B was only in the app target.


Solution

  • This code produces the expected behavior:

    #import <Foundation/Foundation.h>
    
    @interface A : NSObject
    + (NSCache *)itemCache;
    @end
    
    @implementation A
    + (NSCache *)itemCache {
        static NSCache *itemCache;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            itemCache = [[NSCache alloc] init];
        });
        return itemCache;
    }
    
    @end
    
    @interface B : A
    @end
    @implementation B
    @end
    
    
    @interface C : A
    @end
    @implementation C
    @end
    
    
    
    int main(int argc, const char * argv[])
    {
    
        @autoreleasepool {
                NSLog(@"%@ %@ %@", [A itemCache], [B itemCache], [C itemCache]);
    
        }
        return 0;
    }
    

    logs:

    <NSCache: 0x1002000e0> <NSCache: 0x1002000e0> <NSCache: 0x1002000e0>
    

    your issue must be else-where.