在 Objective-C 中,字典对象(Dictionary)用于存储键值对(Key-Value Pairs)。它类似于其他语言中的 Map、Hash 或关联数组。
字典分为两类:
NSDictionary:不可变字典。创建后不能添加、删除或修改元素。NSMutableDictionary:可变字典。可以随时增删改查。
1. 核心规则
- 键(Key) :通常是字符串(
NSString),必须是唯一的。 - 值(Value) :可以是任何对象(
NSNumber,NSString,NSArray等),但不能是nil。 - 无序性:字典内部存储是无序的,遍历时的顺序不一定等同于插入顺序。
2. 快速入门:语法糖(推荐写法)
现代 Objective-C 推荐使用 @ 符号来简化操作:
objectivec
// 创建不可变字典
NSDictionary *dict = @{@"name": @"张三", @"age": @25};
// 读取值
NSString *name = dict[@"name"]; // 结果: 张三
3. 学习代码案例
下面的代码涵盖了从创建到遍历的所有基础操作:
objectivec
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
// --- 1. 创建不可变字典 (NSDictionary) ---
NSDictionary *person = @{
@"id": @101,
@"name": @"Jack",
@"city": @"Shanghai"
};
NSLog(@"字典大小: %lu", person.count);
NSLog(@"Jack 的城市: %@", person[@"city"]);
// --- 2. 创建可变字典 (NSMutableDictionary) ---
NSMutableDictionary *mDict = [NSMutableDictionary dictionary];
// 添加/修改键值对
mDict[@"brand"] = @"Apple"; // 语法糖写法
[mDict setObject:@"M3 Max" forKey:@"cpu"]; // 传统写法
mDict[@"ram"] = @"64GB";
NSLog(@"修改前: %@", mDict);
// 更新值
mDict[@"ram"] = @"128GB";
// 删除值
[mDict removeObjectForKey:@"brand"];
NSLog(@"修改后: %@", mDict);
// --- 3. 字典的遍历 ---
// 方式 A: 快速遍历 (遍历的是所有的 Key)
NSLog(@"--- 开始快速遍历 ---");
for (NSString *key in mDict) {
NSLog(@"键: %@, 值: %@", key, mDict[key]);
}
// 方式 B: Block 遍历 (效率更高,推荐)
[mDict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSLog(@"Block遍历 -> Key: %@, Value: %@", key, obj);
// 如果想停止遍历,可以设置 *stop = YES;
}];
}
return 0;
}
4. 常见操作与对比
| 操作 | 语法 |
|---|---|
| 判断键是否存在 | if (dict[@"key"]) { ... } (如果不存在会返回 nil) |
| 获取所有键 | NSArray *keys = [dict allKeys]; |
| 获取所有值 | NSArray *values = [dict allValues]; |
| 清空字典 | [mDict removeAllObjects]; |
5. 开发者避坑指南(重点)
A. 永远不要插入 nil
字典的键和值都不能为 nil。如果你向字典插入 nil,程序会直接 Crash(崩溃)。
- 错误示例 :
mDict[@"test"] = someObject;// 如果 someObject 是 nil,崩! - 解决办法 :如果确实需要表示"空",请使用
[NSNull null]对象:mDict[@"test"] = [NSNull null];
B. 键的唯一性
如果你向 NSMutableDictionary 插入一个已经存在的键,旧的值会被直接覆盖。
C. 字典与数组的选择
- 数组 (NSArray):通过索引(0, 1, 2...)访问,适合有序列表。
- 字典 (NSDictionary):通过有意义的键("userId", "token")访问,适合存储属性信息,查找速度比数组遍历快得多。
D. 数字处理
字典只能存对象 。如果你想存数字 10,不能直接写 10,必须包装成 NSNumber:
- ❌
dict[@"score"] = 100;// 编译错误 - ✅
dict[@"score"] = @100;// 正确
总结
- 不可变 用
@{...}。 - 可变 用
NSMutableDictionary。 - 取值 用
dict[key]。 - 防崩溃 :在存入变量前,先检查该变量是否为
nil。