NSCache
다짜고짜 차이점을 찾기 전에 NSCache가 뭔지부터 알아보자.
NSCache는 메모리캐싱에 주로 사용되는 객체라고 알려져 있다.
리소스가 부족하면 자동으로 삭제되는 key-value 쌍을 임시로 저장하는 mutable collection 이라고 한다. 여기까지만 봐선 '자동으로 삭제되는' 이라는 부분이 Dictionary와 다른 점인데... 좀 더 알아보자.
Overview를 보니 대놓고 차이점을 설명해주고 있다. 읽어보자.
- 먼저 시스템 메모리를 과도하게 사용하지 않도록하는 자동 삭제 정책을 가진다. 다른 애플리케이션에서 메모리를 필요로할 경우 이 policy가 cache에서 일부 항목을 제거한다.
- Thread-Safe하게 구현되어 있어 따로 lock하지 않아도 다른 스레드에서 캐시의 항목을 추가, 제거, 검색할 수 있다.
- NS(Mutable)Dictionary 객체와 다르게 저장된 Key 객체를 복사하지 않는다.
첫번째와 두번째는 내부적으로 그렇게 구현했겠구나 싶었는데, 마지막 항목은 어떤 의미인지 감이 잘 오지 않았다.
다행히 스택오버플로우에서 바로 좋은 예시를 찾을 수 있었다. (https://stackoverflow.com/questions/69377994/does-the-different-way-of-handling-key-between-nsmutabledictionary-and-nscache)
let mutableDic = NSMutableDictionary()
var dicKey: NSMutableString = "key" // K₁
mutableDic.setObject("one", forKey: dicKey) // K₂
dicKey.setString("changedKey") // still K₁
mutableDic.setObject("two", forKey: dicKey) // K₃
print(mutableDic.object(forKey: "key") ?? "") // "one"
print(mutableDic.object(forKey: "changedKey") ?? "") // "two"
NSMutableDictionary의 Key는 객체를 복사해서 새로운 객체를 생성해서 Key로 등록한다.
let cache = NSCache<NSString, NSString>()
var cacheKey: NSMutableString = "key" // K₁
cache.setObject("one", forKey: cacheKey) // still K₁
cacheKey.setString("changedKey") // still K₁
cache.setObject("two", forKey: cacheKey) // still K₁!
print(cache.object(forKey: "key") ?? "") // ""
print(cache.object(forKey: "changedKey") ?? "") // "two"
반면 NSCache는 객체를 복사하지 않고 그대로 가져간다. 바로 차이점이 느껴진다.
+)이렇게 다르게 구현한 이유에 대해 좀 생각해봤는데... NSDictionary는 값의 확실한 저장이 중요하고, NSCache는 리소스가 부족해지면 삭제되어야한다는 점이 중요해서가 아닐까? 사실 값이 복사되지 않고 참조만 되어서 좋을게 없다. 위의 예시처럼 분명 캐시에 등록을 했는데 값이 존재하지 않는 것처럼 나올 수도 있기 때문이다. 하지만 NSCache는 자동삭제정책을 가지고 있다. 이것이 객체에 참조 정보를 확인해서 참조 횟수가 적으면 좀 빨리 삭제를 한다던가... 그런 원리이기 때문에 복사된 값을 가져가지 않는게 아닐까?
스터디원과 이야기하다 들었는데, 어떤 객체가 복사되려면 NSCopying 프로토콜을 채택한 객체이어야 한다. 따라서 NSDictionary는 그를 채택한 객체만 사용할 수 있다. 하지만 NSCache에서는 그를 채택하지 않은 객체도 Key로 활용할 수 있도록하기 위해 그렇게 했다는 것이 더 설득력있는 이야기인 것 같다!
결론
NSCache와 NSDictionary의 차이점은
- 먼저 시스템 메모리를 과도하게 사용하지 않도록하는 자동 삭제 정책을 가진다. 다른 애플리케이션에서 메모리를 필요로할 경우 이 policy가 cache에서 일부 항목을 제거한다.
- Thread-Safe하게 구현되어 있어 따로 lock하지 않아도 다른 스레드에서 캐시의 항목을 추가, 제거, 검색할 수 있다.
- NS(Mutable)Dictionary 객체와 다르게 저장된 Key 객체를 복사하지 않는다.
이렇게 3가지이다!!
참고
'🍎 Apple > Swift' 카테고리의 다른 글
[Swift] Copy on write (2) | 2022.01.26 |
---|---|
[Swift] 문자열 처리 (0) | 2022.01.22 |
[Swift] UserDefaults와 Codable, NSCoding (2) | 2022.01.01 |
[Swift] Dynamic Dispatch 줄이기 (0) | 2021.12.16 |
[Swift] Codable Protocol (2) | 2021.09.02 |