You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NSMutableDictionary与NSCache的Key处理机制:Copy vs Retain的差异、后果及优缺点解析

NSMutableDictionary vs NSCache: Copy vs Retain for Keys, Explained

Great question—let’s break this down step by step, because your test case uses immutable NSString which hides the real difference between copy vs retain behavior for keys. Let’s start with why your current code doesn’t show a discrepancy, then dive into actual examples that highlight the core differences, and finally cover the pros and cons of each approach.

Why Your Test Results Look the Same

You’re using NSString, an immutable type—when you run dicKey = "changedKey", you aren’t modifying the original "key" object. Instead, you’re just pointing the dicKey variable to a brand new string. Both NSMutableDictionary (which copies keys) and NSCache (which retains keys) hold onto the original "key" object, so your lookup results end up identical. To see the real gap, we need to use a mutable object as the key, like NSMutableString.

Real-World Example with Mutable Keys

Let’s test with a key that can be modified after being added to the collection:

NSMutableDictionary (Copy Behavior)

let mutableDic = NSMutableDictionary()
let dicKey = NSMutableString(string: "key")
mutableDic.setObject("one", forKey: dicKey)

// Modify the original key's content
dicKey.setString("changedKey")
mutableDic.setObject("two", forKey: dicKey)

// Results: Both keys work as expected
print(mutableDic.object(forKey: "key") ?? "") // "one"
print(mutableDic.object(forKey: "changedKey") ?? "") // "two"

When you add a key to NSMutableDictionary, it creates a copy of the key (since NSMutableString conforms to NSCopying). So when you modify the original dicKey, the dictionary still holds the original "key" copy. The second setObject uses a copy of the modified key, creating two separate, stable key-value pairs.

NSCache (Retain Behavior)

let cache = NSCache<NSMutableString, NSString>()
let cacheKey = NSMutableString(string: "key")
cache.setObject("one", forKey: cacheKey)

// Modify the original key's content
cacheKey.setString("changedKey")
cache.setObject("two", forKey: cacheKey)

// Results: Original key is lost, only the modified key works
print(cache.object(forKey: "key") ?? "") // "" (empty)
print(cache.object(forKey: "changedKey") ?? "") // "two"

NSCache only retains the original key object—no copy is made. When you modify cacheKey’s content, the key inside the cache changes too. The original "key" entry is effectively lost, and the second setObject overwrites the now-modified key with "two".

Pros of Retaining Keys (NSCache’s Approach)

  • No NSCopying requirement: You don’t have to implement NSCopying for custom key types, cutting down on boilerplate code.
  • Better performance for immutable keys: For inherently unchangeable types like NSString or NSNumber, retaining avoids the unnecessary overhead of creating a copy.
  • Dynamic key sync (rare use case): In niche scenarios where you want the cache’s key to reflect changes to the original object (though this is usually risky, as it breaks stable key-value mapping), retain keeps the cache linked to the key’s live state.

Pros of Copying Keys (NSMutableDictionary’s Approach)

  • Guaranteed key stability: This is the biggest win. By copying the key, you ensure external changes to the original key object can’t break the dictionary’s internal mapping. The dictionary holds a fixed, unchanging copy, so your key-value pairs stay reliable.
  • Follows dictionary semantics: Dictionaries are designed to map stable identifiers to values. Copying enforces that keys can’t mutate after being added, preventing unexpected lost entries or corrupted lookups.
  • Safety with mutable objects: If you accidentally use a mutable object as a key (like NSMutableString), copying protects you from unintended side effects that would break your dictionary’s functionality.

Final Takeaway

Copying keys is all about stability and reliability—perfect for NSMutableDictionary, where you need consistent key-value mappings. Retaining keys prioritizes simplicity and performance (for immutable keys) and avoids NSCopying requirements—ideal for NSCache, which is optimized for temporary, flexible storage where key stability is less critical.

内容的提问来源于stack exchange,提问作者naljin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 14:47:45