参考 https://www.jianshu.com/p/2fd9680b46f6
哈希概念:哈希表的本质是一个数组,数组中每一个元素称为一个箱子(bin),箱子中存放的是键值对。
简单了解总结,
1.NSMapTable 结构体里面包含一个map数组,数组里面存储
2.NSConcreteMapTable
将键和值添加到表中。<br />
*如果表中已存在等号,则替换其映射值
*使用新的,无需更换密钥本身。<br
BC5ACD13-BD84-4FFB-B09E-8E7FBBF0D700.png
Nsdictionary:::::::
//根据key来 存储位置bucket种位置,
GSIMapBucketForKey(GSIMapTable map, GSIMapKey key)
{
return GSIMapPickBucket(GSI_MAP_HASH(map, key),
map->buckets, map->bucketCount);
}
GSIMapPickBucket(unsigned hash, GSIMapBucket buckets, uintptr_t bucketCount)
{
return buckets + hash % bucketCount;
}
//Bucket 里面存储nodeCount 和fristNode
struct _GSIMapBucket {
uintptr_t nodeCount; /* Number of nodes in bucket. */
GSIMapNode firstNode; /* The linked list of nodes. */
};
//将键和值添加到表中。<br />
*如果表中已存在等号,则替换其映射值
*使用新的,无需更换密钥本身。<br />
*如果key等于表的notAKeyMarker字段
* NSMapTableKeyCallBacks,引发NSInvalidArgumentException。
void NSMapInsert(NSMapTable *table, const void *key, const void *value)
{
if (table == nil)
{
[NSException raise: NSInvalidArgumentException
format: @"Attempt to place key-value in null table"];
}
if (object_getClass(table) == concreteClass)
{
GSIMapTable t = (GSIMapTable)table;
GSIMapNode n;
if (t->legacy == YES)
{
if (key == t->cb.old.k.notAKeyMarker)
{
[NSException raise: NSInvalidArgumentException
format: @"Attempt to place notAKeyMarker in map"];
}
}
else if (key == 0)
{
[NSException raise: NSInvalidArgumentException
format: @"Attempt to place nil key in map"];
}
n = GSIMapNodeForKey(t, (GSIMapKey)key);
if (n == 0)
{
GSIMapAddPair(t, (GSIMapKey)key, (GSIMapVal)value);
t->version++;
}
else if (n->value.ptr != value)
{
GSIMapVal tmp = n->value;
n->value = (GSIMapVal)value;
GSI_MAP_RETAIN_VAL(t, n->value);
GSI_MAP_RELEASE_VAL(t, tmp);
t->version++;
}
}
else
{
[table setObject: (id)value forKey: (id)key];
}
}
网友评论