1. NSArray
NSArray作為一個存儲對象的有序集合,可能是被使用最多的集合類。
性能特征
在數組的開頭和結尾插入/刪除元素通常是一個O(1)操作,而隨機的插入/刪除通常是 O(N)的。
有用的方法
NSArray的大多數方法使用isEqual:來檢查對象間的關系(例如containsObject:)。有一個特別的方法
indexOfObjectIdenticalTo:
用來檢查指針相等,如果你確保在同一個集合中搜索,那么這個方法可以很大的提升搜索速度。
更多相關資料參考
2. NSDictionary
一個字典存儲任意的對象鍵值對。 由于歷史原因,初始化方法使用相反的對象到值的方法,
[NSDictionary dictionaryWithObjectsAndKeys:object, key, nil]
而新的快捷語法則從key開始
@{key : value, ...}
NSDictionary中的鍵是被拷貝的并且需要是恒定的。如果在一個鍵在被用于在字典中放入一個值后被改變,那么這個值可能就會變得無法獲取了。一個有趣的細節,在NSDictionary中鍵是被拷貝的,而在使用一個toll-free橋接的CFDictionary時卻只被retain。CoreFoundation類沒有通用對象的拷貝方法,因此這時拷貝是不可能的(*)。這只適用于使用CFDictionarySetValue()的時候。如果通過setObject:forKey使用toll-free橋接的CFDictionary,蘋果增加了額外處理邏輯來使鍵被拷貝。反過來這個結論則不成立 — 轉換為CFDictionary的NSDictionary對象,對其使用CFDictionarySetValue()方法會調用回setObject:forKey并拷貝鍵。
3. NSCache
NSCache是一個非常奇怪的集合。在iOS 4/Snow Leopard中加入,默認為可變
并且線程安全
的。這使它很適合緩存那些創建起來代價高昂的對象。它自動對內存警告
做出反應并基于可設置的成本
清理自己。與NSDictionary相比,鍵是被retain而不是被拷貝
的。
NSCache的回收方法是不確定的,在文檔中也沒有說明。向里面放一些類似圖片那樣比被回收更快填滿內存的大對象不是個好主意。(這是在PSPDFKit中很多跟內存有關的crash的原因,在使用自定義的基于LRU的鏈表的緩存代碼之前,我們起初使用NSCache存儲事先渲染的圖片。)
NSCache可以設置撐自動回收實現了NSDiscardableContent協議的對象。實現該屬性的一個比較流行的類是同時間加入的NSPurgeableData,但是在OS X 10.9之前,是非線程安全的(沒有信息表明這是否也影響到iOS或者是否在iOS 7中被修復了)。
NSCache性能
那么NSCache如何承受NSMutableDictionary的考驗?加入的線程安全必然會帶來一些消耗。
4. iOS 構建緩存時選 NSCache 而非NSDictionary
當系統資源將要耗盡時,NSCache可以自動刪減緩存。如果采用普通的字典,那么就要自己編寫掛鉤,在系統通知時手動刪減緩存,NSCache會先行刪減 時間最久為被使用的對象
NSCache 并不會拷貝鍵,而是會保留它。此行為用NSDictionary也可以實現,但是需要編寫比較復雜的代碼。NSCache對象不拷貝鍵的原因在于,很多時候鍵都是不支持拷貝操作的對象來充當的。因此NSCache對象不會自動拷貝鍵,所以在鍵不支持拷貝操作的情況下,該類比字典用起來更方便
NScache是線程安全的,NSDictionary不是。在開發者自己不編寫加鎖代碼的前提下,多個線程可以同時訪問NSCache。對緩存來說,線程安全通常是很重要的,因為開發者可能在某個線程中讀取數據,此時如果發現緩存里找不著指定的鍵,那么就要下載該鍵對應的數據了
更多:iOS面試題合集