【OC梳理】NSPointerArray、NSMapTable汇歹、NSHashTable

NSPointerArray屁擅、NSMapTable、NSHashTable是iOS 6.0之后新增的集合類型产弹,對應于原來的NSArray派歌、NSSet、NSDictionary。

NSPointerArray

NSPointerArray和NSArray/NSMutableArray一樣胶果,用于有序的插入或移除常挚。不同的是:

  • 可以存儲 nil,并且 nil 還參與 count 的計算稽物。
  • count 值可以直接設置奄毡,如果直接設置count,那么會使用 nil 占位贝或。
  • 可以使用 weak 來修飾元素吼过,可以添加所有的指針類型。
  • 可以通過 for...in 來進行遍歷咪奖。

也有一些缺點:

  • 操作均基于 index盗忱,無法通過 object 來進行操作;
  • 無法直接插入 array羊赵,或用 array 初始化趟佃;
  • 查找功能沒有 NSArray 強大;
  • 沒有逆序昧捷、排序等 API 提供

初始化

NSPointerArray 有兩個初始化方法:

- (instancetype)initWithOptions:(NSPointerFunctionsOptions)options;
- (instancetype)initWithPointerFunctions:(NSPointerFunctions *)functions; 

+ (NSPointerArray *)pointerArrayWithOptions:(NSPointerFunctionsOptions)options;
+ (NSPointerArray *)pointerArrayWithPointerFunctions:(NSPointerFunctions *)functions;

NSPointerFunctionsOptions主要分為三大類:

內存管理

  • NSPointerFunctionsStrongMemory:缺省值闲昭,在 CG 和 MRC 下強引用成員
  • NSPointerFunctionsZeroingWeakMemory:已廢棄,在 GC 下靡挥,弱引用指針序矩,防止懸掛指針
  • NSPointerFunctionsMallocMemory 與 NSPointerFunctionsMachVirtualMemory:3 用于 Mach 的虛擬內存管理
  • NSPointerFunctionsWeakMemory:在 CG 或者 ARC 下,弱引用成員

特性跋破,用于標明對象判等方式

  • NSPointerFunctionsObjectPersonality:hash簸淀、isEqual、對象描述
  • NSPointerFunctionsOpaquePersonality:pointer 的 hash 毒返、直接判等
  • NSPointerFunctionsObjectPointerPersonality:pointer 的 hash租幕、直接判等、對象描述
  • NSPointerFunctionsCStringPersonality:string 的 hash拧簸、strcmp 函數(shù)劲绪、UTF-8 編碼方式的描述
  • NSPointerFunctionsStructPersonality:內存 hash、memcmp 函數(shù)
  • NSPointerFunctionsIntegerPersonality:值的 hash

內存標識

  • NSPointerFunctionsCopyIn:根據(jù)第二類的選擇狡恬,來具體處理珠叔。

可以使用多個組合進行初始化:

NSPointerFunctionsOptions opt = NSPointerFunctionsStrongMemory | NSPointerFunctionsObjectPersonality | NSPointerFunctionsCopyIn;
NSPointerArray *point = [[NSPointerArray alloc]initWithOptions:opt];

NSPointerFunctions
使用NSPointerFunctions可以自定義NSPointerArray對元素的處理方式:如何內存管理、如何hash弟劲、如何判斷相等(isEqual)祷安。
NSPointerFunctions初始化時可設置NSPointerFunctionsOptions

- (instancetype)initWithOptions:(NSPointerFunctionsOptions)options;
+ (NSPointerFunctions *)pointerFunctionsWithOptions:(NSPointerFunctionsOptions)options;

如果需要自定義實現(xiàn)函數(shù),可以使用下面的對應屬性:

// 自定義指針函數(shù)
// hash函數(shù)
@property (nullable) NSUInteger (*hashFunction)(const void *item, NSUInteger (* _Nullable size)(const void *item));
// isEqual函數(shù)
@property (nullable) BOOL (*isEqualFunction)(const void *item1, const void*item2, NSUInteger (* _Nullable size)(const void *item));
// size函數(shù)
@property (nullable) NSUInteger (*sizeFunction)(const void *item);
// 描述函數(shù)
@property (nullable) NSString * _Nullable (*descriptionFunction)(const void *item);

// 自定義內存配置
// 移除元素時的處理函數(shù)
@property (nullable) void (*relinquishFunction)(const void *item, NSUInteger (* _Nullable size)(const void *item));
// 添加元素時的處理函數(shù)
@property (nullable) void * _Nonnull (*acquireFunction)(const void *src, NSUInteger (* _Nullable size)(const void *item), BOOL shouldCopy);

可以自行實現(xiàn)函數(shù),然后將函數(shù)指針賦給對應屬性即可兔乞,比如汇鞭,isEqual:

static BOOL IsEqual(const void *item1, const void *item2, NSUInteger (*size)(const void *item)) {
    return *(const int *)item1 == *(const int *)item2;
}

NSPointerFunctions *functions = [[NSPointerFunctions alloc] init];
[functions setIsEqualFunction:IsEqual]; 

操作數(shù)組

添加元素:

- (void)addPointer:(nullable void *)pointer;

移除元素:

- (void)removePointerAtIndex:(NSUInteger)index; 

插入元素:

- (void)insertPointer:(nullable void *)item atIndex:(NSUInteger)index;

替換元素:

- (void)replacePointerAtIndex:(NSUInteger)index withPointer:(nullable void *)item;

如果想實現(xiàn)類似Array的根據(jù)下標賦值,可以為它添加一個分類:


@interface NSPointerArray(Set)

/// 設置目標位置的值
- (void)setObject:(id)anObject
          atIndex:(NSUInteger)idx;

@end

@implementation NSPointerArray(Set)

- (void)setObject:(id)anObject
          atIndex:(NSUInteger)idx{
    if (self.count > idx) {
       self.count = idx + 2;
    }
    [self insertPointer:(__bridge void * _Nullable)(anObject) atIndex:idx];
}

@end

NSMapTable

與 NSMapTable 對應的凉唐,是 NSMutableDictionary。除了 集合的共有特點以外霍骄,比起傳統(tǒng)字典台囱,它還有一些優(yōu)勢:

  • key 可以不用遵循 NSCopying 協(xié)議;
  • key 和 value 的內存管理方式可以分開读整,如:key 是強引用簿训,value 是弱引用;

相比起 NSPointerArray米间,NSMapTable 的初始化方法要多得多:

// 雖然有 capacity 參數(shù)强品,但實際沒用到
- (instancetype)initWithKeyOptions:(NSPointerFunctionsOptions)keyOptions valueOptions:(NSPointerFunctionsOptions)valueOptions capacity:(NSUInteger)initialCapacity;
- (instancetype)initWithKeyPointerFunctions:(NSPointerFunctions *)keyFunctions valuePointerFunctions:(NSPointerFunctions *)valueFunctions capacity:(NSUInteger)initialCapacity;
 
+ (NSMapTable<KeyType, ObjectType> *)mapTableWithKeyOptions:(NSPointerFunctionsOptions)keyOptions valueOptions:(NSPointerFunctionsOptions)valueOptions;
 
// 返回指定 key、value 內存管理類型的 map
+ (NSMapTable<KeyType, ObjectType> *)strongToStrongObjectsMapTable NS_AVAILABLE(10_8, 6_0);
+ (NSMapTable<KeyType, ObjectType> *)weakToStrongObjectsMapTable NS_AVAILABLE(10_8, 6_0);
+ (NSMapTable<KeyType, ObjectType> *)strongToWeakObjectsMapTable NS_AVAILABLE(10_8, 6_0);
+ (NSMapTable<KeyType, ObjectType> *)weakToWeakObjectsMapTable NS_AVAILABLE(10_8, 6_0);

其實屈糊,這么多的初始化方法就對應著四種搭配:

  • key 為 strong的榛,value 為 strong
  • key 為 strong,value 為 weak
  • key 為 weak逻锐,value 為 strong
  • key 為 weak夫晌,value 為 weak

當用 weak 修飾 key 或 value 時,有一方被釋放昧诱,則該鍵值對移除晓淀。

NSHashTable

NSHashTable 對應 NSMutableSet,它的 API 更為簡單鳄哭,與 NSMapTable 同樣要糊,初始化方法的 capacity 并未生效纲熏。

- (instancetype)initWithOptions:(NSPointerFunctionsOptions)options capacity:(NSUInteger)initialCapacity;
- (instancetype)initWithPointerFunctions:(NSPointerFunctions *)functions capacity:(NSUInteger)initialCapacity;

值得注意的是妆丘,NSHashTable 有一個 allObjectes 的屬性,返回 NSArray局劲,即使 NSHashTable 是弱引用成員勺拣,allObjects 依然會對成員進行強引用。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末鱼填,一起剝皮案震驚了整個濱河市药有,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌苹丸,老刑警劉巖愤惰,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異赘理,居然都是意外死亡宦言,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門商模,熙熙樓的掌柜王于貴愁眉苦臉地迎上來奠旺,“玉大人蜘澜,你說我怎么就攤上這事∠炀危” “怎么了鄙信?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長忿晕。 經常有香客問我装诡,道長,這世上最難降的妖魔是什么践盼? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任慎王,我火速辦了婚禮,結果婚禮上宏侍,老公的妹妹穿的比我還像新娘赖淤。我一直安慰自己,他們只是感情好谅河,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布咱旱。 她就那樣靜靜地躺著,像睡著了一般绷耍。 火紅的嫁衣襯著肌膚如雪吐限。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天褂始,我揣著相機與錄音诸典,去河邊找鬼。 笑死崎苗,一個胖子當著我的面吹牛狐粱,可吹牛的內容都是我干的。 我是一名探鬼主播胆数,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼肌蜻,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了必尼?” 一聲冷哼從身側響起蒋搜,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎判莉,沒想到半個月后豆挽,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡券盅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年帮哈,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片渗饮。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡但汞,死狀恐怖宿刮,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情私蕾,我是刑警寧澤僵缺,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站踩叭,受9級特大地震影響磕潮,放射性物質發(fā)生泄漏。R本人自食惡果不足惜容贝,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一自脯、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧斤富,春花似錦膏潮、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至油额,卻和暖如春叠纷,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背潦嘶。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工涩嚣, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人掂僵。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓航厚,卻偏偏與公主長得像,于是被迫代替她去往敵國和親看峻。 傳聞我的和親對象是個殘疾皇子阶淘,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內容