OC 为自己的类增加下标支持 obj[key] = value

本文探讨了Objective-C中字典和数组下标使用的原理及其背后的支持机制,详细解析了不同类型的集合如何通过遵循特定协议来实现下标取值与赋值的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


原文地址:http://www.jianshu.com/p/0bb1b6bee194


楔子

本文是前面一篇文章《[iOS] [OC] 可变字典下标[]语法糖不是setObject:forKey: 而等效于KVC》探索的新发现。

下标的原理

下标subscripting是OC开发中常用的字典和数组的取值和设值方式,其中不可变字典和数组可以取值,可变字典和数组通过继承可以取值,同时还支持设值

    NSDictionary *dic = @{@"key":@"value"};
    NSString *value = dic[@"key"];  // 不可变字典取值

    NSMutableDictionary *mutableDic = [NSMutableDictionary dictionary];
    mutableDic[@"key"] = @"value";  // 可变字典设值
    NSString *mValue = mutableDic[@"key"]; // 可变字典取值


    NSArray *array = @[@1, @2];
    NSNumber *num = array[0]; // 不可变数组取值

    NSMutableArray *mutableArray = [NSMutableArray array];
    [mutableArray addObject:@1];
    mutableArray[0] = @2;   // 可变数组设值
    NSNumber *mNum = mutableArray[0];  // 可变数组取值

下标的使用是iOS6以后支持的,取值和设值的原理是编译器调用了一套非正式的协议informal-protocol,这套协议的文档将下标分为两类,字典样式dictionary-style和数组样式array-style,分别要求实现对应协议的方法,从而支持下标的使用

// 字典样式
- (nullable ObjectType)objectForKeyedSubscript:(KeyType)key; // 取值
- (void)setObject:(nullable ObjectType)obj forKeyedSubscript:(KeyType <NSCopying>)key; // 设值

// 数组样式
- (ObjectType)objectAtIndexedSubscript:(NSUInteger)idx ; // 取值
- (void)setObject:(ObjectType)obj atIndexedSubscript:(NSUInteger)idx ; // 设值

除了实现实际需求的方法外,还需要定义的类在显示的声明或者遵从包含上述需求的特定方法的协议,
从而能被编译器正确识别。

此时回过头去看苹果的NSArrayNSMutableArrayNSDictionaryNSMutableDictionay在头文件有方法的声明,以及JSValueJSContext都有SubscriptSupportcategory,以及第三方的比如谷歌ProtobufferGPBDicionary类,数据库管理FMDBFMResultSet类以及钥匙串管理类UICKeyChainStore都有相关的声明和实现。

小结

如此以来就可以解释mutableDic[key] = nil不会出错的原因了,因为使用的是下标方法,而根据apple的可变字典文档的说明,传入nil会移除对应keyvalue



作者:席萍萍Brook_iOS深圳
链接:http://www.jianshu.com/p/0bb1b6bee194
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

<think>好的,我现在需要解决用户的问题:如何在JavaScript中将似“key1=value1||key2=value2||key3=value3”的字符串转换为JSON对象。首先,我得仔细分析用户提供的示例字符串结构,然后思考如何一步步解析它。 首先,用户给出的字符串格式是键值对通过“||”分隔,每个键值对内部用“=”连接。例如,“key1=value1||key2=value2||key3=value3”。目标是将这个字符串转换为JSON对象,也就是JavaScript中的对象字面量,如:{ key1: 'value1', key2: 'value2', key3: 'value3' }。 接下来,我需要考虑如何拆分字符串。第一步应该是将整个字符串按照“||”分割成多个键值对。在JavaScript中,可以使用split方法,传入分隔符。但要注意,split的参数是一个正则表达式或字符串,这里的分隔符是“||”,所以正确的写法应该是split('||'),这样就能得到一个包含各个键值对的数组。 得到键值对数组后,每个元素如“key1=value1”需要进一步处理。需要遍历这个数组,对每个元素再次用“=”进行分割,得到键和值。这里要注意可能存在等号在值中的情况,比如“key=part1=part2”,这时候简单的split('=')会导致错误的分割。不过根据用户提供的示例,这种情况可能不存在,但需要确认用户的需求。如果值中确实包含等号,可能需要更复杂的处理,比如限制只分割第一个等号。不过用户的问题中没有提到这种情况,暂时假设每个键值对的等号只有一个,分割成键和值两部分。 接下来,处理每个键值对的键和值。分割后的数组第一个元素是键,第二个是值。将它们分别存储到对象中。需要注意的是,值可能包含空格或其他字符,是否需要trim处理?例如,如果字符串是“key1 = value1 || key2=value2”,分割后的键可能有空格,这时候是否需要去除两边的空格。根据用户提供的示例,可能不需要,但为了健壮性,可以考虑对键和值都进行trim处理。 然后,将这些键值对组合成一个对象。遍历分割后的数组,逐个处理,将键作为属性名,值作为属性值添加到对象中。 最后,需要考虑异常情况,比如空字符串,或者键值对不符合格式的情况,但用户的问题可能假设输入是正确的,暂时不处理异常。 现在,整合这些步骤,写出代码。首先用split('||')分割成键值对数组,然后遍历每个键值对,用split('=')分割,trim键和值,然后添加到对象中。 测试一下示例字符串:“key1=value1||key2=value2||key3=value3”应该转换为{ key1: 'value1', key2: 'value2', key3: 'value3' }。如果存在空格,比如“key1 = value1 || key2=value2”,处理后键和值会被trim,变成正确的。 可能的代码: function parseStringToJSON(str) { const obj = {}; const pairs = str.split('||'); for (const pair of pairs) { const [key, value] = pair.split('=').map(s => s.trim()); if (key && value !== undefined) { obj[key] = value; } } return obj; } 然后,用户可能需要将这个对象转换为JSON字符串,可以使用JSON.stringify,但用户的问题可能只需要得到对象。 另外,是否需要处理值中的特殊字符,比如如果值是数字,是否要转换为数字型?根据示例中的value1等,可能都是字符串,所以默认保持为字符串。 综上,这就是解决这个问题的步骤。</think>以下是将字符串 `key1=value1||key2=value2||key3=value3` 转换为 JSON 对象的逐步方法: --- ### **步骤 1:分割键值对** 首先用 `||` 分割字符串,得到独立的键值对: ```javascript const str = "key1=value1||key2=value2||key3=value3"; const pairs = str.split("||"); // 结果: ["key1=value1", "key2=value2", "key3=value3"] ``` --- ### **步骤 2:解析每个键值对** 遍历每个键值对,用 `=` 分割键和值,并处理可能的空格: ```javascript const obj = {}; for (const pair of pairs) { // 分割键和值,并去除首尾空格 const [key, value] = pair.split("=").map(s => s.trim()); // 将键值对存入对象 if (key && value !== undefined) { obj[key] = value; } } ``` --- ### **步骤 3:输出 JSON 对象** 最终生成的 JSON 对象为: ```javascript console.log(obj); // { key1: "value1", key2: "value2", key3: "value3" } ``` --- ### **完整代码** ```javascript function parseStringToJSON(str) { const obj = {}; const pairs = str.split("||"); for (const pair of pairs) { const [key, value] = pair.split("=").map(s => s.trim()); if (key && value !== undefined) { obj[key] = value; } } return obj; } // 示例用法 const result = parseStringToJSON("key1=value1||key2=value2||key3=value3"); console.log(result); // { key1: 'value1', key2: 'value2', key3: 'value3' } ``` --- ### **注意事项** 1. **空值处理**:如果键或值为空(如 `key1=||key2=value2`),代码会跳过无效键值对。 2. **特殊符号**:如果值包含 `=` 或 `||`,需要更复杂的解析(如正则表达式),但上述代码适用于简单场景。 3. **型转换**:所有值默认是字符串型,如需数字/布尔值,需额外处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值