iosobjective-cnscache

Why SDWebImage Used LOCK on NSCache?


In NSCache document Apple says

You can add, remove, and query items in the cache from different threads without having to lock the cache yourself.


Solution

  • In short, they don't use LOCK on NSCache. Here's their caches implementation.

    They have multiple different types of cache, and the only one which is wrapped in LOCK/UNLOCK is weakCache:

    @property (nonatomic, strong, nonnull) NSMapTable<KeyType, ObjectType> *weakCache; // strong-weak cache
    

    Which is an object of NSMapTable. NSMapTable is not thread safe:

    // `setObject:forKey:` just call this with 0 cost. Override this is enough
    - (void)setObject:(id)obj forKey:(id)key cost:(NSUInteger)g {
        [super setObject:obj forKey:key cost:g];
        if (!self.config.shouldUseWeakMemoryCache) {
            return;
        }
        if (key && obj) {
            // Store weak cache
            LOCK(self.weakCacheLock);
            [self.weakCache setObject:obj forKey:key];
            UNLOCK(self.weakCacheLock);
        }
    }