你不知道的集合類

Foundation框架中的集合類卷哩,一般使用到的是集合吸祟、字典匙头、數(shù)組以及它們的可變版本漫谷,NSCache, NSHashTable, NSMapTable 了解一下。

NSCache是專門用來處理內(nèi)存緩存的類蹂析,使用方法跟NSMutableDictionary類似舔示,但卻又有很大的不同:

  1. NSMutableDictionary會對key進(jìn)行copy,value retain, NSCache不會對key進(jìn)行copy电抚, 所以NSMutableDictionary的key要遵守NSCopy協(xié)議惕稻。
  2. NSCache線程安全, NSMutableDictionary非線程安全。
  3. NSCache有對象淘汰策略蝙叛,通過在存值的時候指定cost,當(dāng)總cost或者key-value個數(shù)達(dá)到limit時俺祠,會進(jìn)行對象釋放(非LRU算法)。這種淘汰策略在沒收到內(nèi)存警告是也會執(zhí)行借帘,從而降低內(nèi)存峰值(minimizing its memory footprint)锻煌。
  4. Retrieving something from an NSCache object returns an autoreleased result.

NSHashTable

NSHashTable 是 NSSet 的通用版本,和 NSSet / NSMutableSet 不同的是姻蚓,NSHashTable 具有下面這些特性:

  1. NSSet / NSMutableSet 持有成員的強引用宋梧,通過 hash 和 isEqual: 方法來檢測成員的散列值和相等性。
  2. NSHashTable 是可變的狰挡,沒有不可變的對應(yīng)版本捂龄。
  3. NSHashTable 可以持有成員的弱引用释涛。
  4. NSHashTable 可以在加入成員時進(jìn)行 copy 操作。
  5. NSHashTable 可以存儲任意的指針倦沧,通過指針來進(jìn)行相等性和散列檢查唇撬。
    NSHashTable 能保存對象弱引用, 對象釋放后能從中移除用法展融。用法如下:
  • (void)hashTableTest {
    _hash = [NSHashTable hashTableWithOptions:NSPointerFunctionsWeakMemory];
    [_hash addObject:@"foo"];
    [_hash addObject:@"bar"];
    [_hash addObject:@42];
    [_hash addObject:@"bar"];
    Person *obj = [Person new];
    NSLog(@"%p", obj);
    NSLog(@"Retain count is %ld", CFGetRetainCount((__bridge CFTypeRef)obj));
    [_hash addObject:obj];
    NSLog(@"Retain count is %ld", CFGetRetainCount((__bridge CFTypeRef)obj));
    NSLog(@"Members: %@", [_hash allObjects]);
    }

我們在viewdidload和viewWillAppear中分別調(diào)用[_hash allObjects]窖认,結(jié)果如下:

2018-09-23 19:26:48.341916+0800 NSDictonary&NSMapTable&NSHashTable&NSCache[33628:10708256] 0x600000015580
2018-09-23 19:26:48.342115+0800 NSDictonary&NSMapTable&NSHashTable&NSCache[33628:10708256] Retain count is 1
2018-09-23 19:26:48.342247+0800 NSDictonary&NSMapTable&NSHashTable&NSCache[33628:10708256] Retain count is 1
2018-09-23 19:26:48.342469+0800 NSDictonary&NSMapTable&NSHashTable&NSCache[33628:10708256] Members: (
"<Person: 0x600000015580>",
bar,
42,
foo
)
2018-09-23 19:26:48.342594+0800 NSDictonary&NSMapTable&NSHashTable&NSCache[33628:10708256] Members: (
"<Person: 0x600000015580>",
bar,
42,
foo
)
2018-09-23 19:26:48.348660+0800 NSDictonary&NSMapTable&NSHashTable&NSCache[33628:10708256] Person--dealloc
2018-09-23 19:26:48.385762+0800 NSDictonary&NSMapTable&NSHashTable&NSCache[33628:10708256] Members: (
bar,
42,
foo
)

對對象的內(nèi)存管理參考NSPointerFunctions.Options

NSMapTable

NSMapTable 是 NSMutableDictionary 的增強版。和NSMutableDictionary 不同的是告希,NSMapTable 具有下面這些特性:

用法:

  • (void)maptableTest {
    id obj = [Person new];
    NSLog(@"Retain count is %ld", CFGetRetainCount((__bridge CFTypeRef)obj));
    _map = [NSMapTable mapTableWithKeyOptions:NSMapTableStrongMemory
    valueOptions:NSMapTableWeakMemory];
    [_map setObject:obj forKey:@"foo"];
    NSLog(@"Retain count is %ld", CFGetRetainCount((__bridge CFTypeRef)obj));
    NSLog(@"Keys: %@", [[_map keyEnumerator] allObjects]);
    }

在viewDidLoad和viewDidAppear中分別調(diào)用NSLog(@"Keys: %@", [[_map keyEnumerator] allObjects]); 打印如下:

2018-09-23 19:39:23.192198+0800 NSDictonary&NSMapTable&NSHashTable&NSCache[33761:10717870] Retain count is 1

2018-09-23 19:39:23.192397+0800 NSDictonary&NSMapTable&NSHashTable&NSCache[33761:10717870] Retain count is 1
2018-09-23 19:39:23.192623+0800 NSDictonary&NSMapTable&NSHashTable&NSCache[33761:10717870] Keys: (
foo
)
2018-09-23 19:39:23.192754+0800 NSDictonary&NSMapTable&NSHashTable&NSCache[33761:10717870] Keys: (
foo
)
2018-09-23 19:39:23.195027+0800 NSDictonary&NSMapTable&NSHashTable&NSCache[33761:10717870] Person--dealloc
2018-09-23 19:39:23.213502+0800 NSDictonary&NSMapTable&NSHashTable&NSCache[33761:10717870] Keys: (
)

對對象的內(nèi)存管理參考NSMapTableOptions, 值得注意的是SDWebImage最新版中將圖片緩存的NSCache換為了NSMapTable扑浸,能夠有效降低內(nèi)存峰值。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末燕偶,一起剝皮案震驚了整個濱河市喝噪,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌指么,老刑警劉巖酝惧,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異伯诬,居然都是意外死亡晚唇,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門盗似,熙熙樓的掌柜王于貴愁眉苦臉地迎上來缺亮,“玉大人,你說我怎么就攤上這事桥言。” “怎么了葵礼?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵号阿,是天一觀的道長。 經(jīng)常有香客問我鸳粉,道長扔涧,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任届谈,我火速辦了婚禮枯夜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘艰山。我一直安慰自己湖雹,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布曙搬。 她就那樣靜靜地躺著摔吏,像睡著了一般鸽嫂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上征讲,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天据某,我揣著相機(jī)與錄音,去河邊找鬼诗箍。 笑死癣籽,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的滤祖。 我是一名探鬼主播筷狼,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼氨距!你這毒婦竟也來了桑逝?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤俏让,失蹤者是張志新(化名)和其女友劉穎楞遏,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體首昔,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡寡喝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了勒奇。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片预鬓。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖赊颠,靈堂內(nèi)的尸體忽然破棺而出格二,到底是詐尸還是另有隱情,我是刑警寧澤竣蹦,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布顶猜,位于F島的核電站,受9級特大地震影響痘括,放射性物質(zhì)發(fā)生泄漏长窄。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一纲菌、第九天 我趴在偏房一處隱蔽的房頂上張望挠日。 院中可真熱鬧,春花似錦翰舌、人聲如沸嚣潜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽郑原。三九已至唉韭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間犯犁,已是汗流浹背属愤。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留酸役,地道東北人住诸。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像涣澡,于是被迫代替她去往敵國和親贱呐。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,722評論 2 345