关于OC中用字典添加联系人到通讯录中常见的错误

情景案例:根据联系人的姓名的首字母进行分组,将首字母同为A的放在同一个数组中,以此类推。

首先关于这个情景,我们很有可能想到将字典的key值设置为A到Z的26个字母,然后我们进行添加的时候直接根据key值来添加。(这种做法虽然看上去比较繁琐,但是有益于理解,个人不是很推荐)

- (void)addPeople:(People *)people
{

NSMutableArray *key = [NSMutableArray arrayWithObjects:@"A",@"B",@"C",@"D",@"E",@"F",@"G",@"H",@"I",@"J",@"K",@"L",@"M",@"N",@"O",@"P",@"Q",@"R",@"S",@"T",@"U",@"V",@"W",@"X",@"Y",@"Z",nil];
NSMutableArray *AllValue = [NSMutableArray array];
for (int i = 0; i < 26; i ++) {
    NSMutableArray *EachValue = [NSMutableArray array];
    [AllValue addObject:EachValue];
}
_dictionary = [[NSMutableDictionary alloc]initWithObjects:AllValue forKeys:key];
    
    [[_dictionary objectForKey:people.group] addObject:people];
}

这种写法很繁琐 ,先要创建三种数组,一个存放key值的数组还有一个是每个key值对应的数组(这里用for循环26次),还有一个是Value大数组包含26个小数组。这时候对应的key值添加对象就不存在覆盖前面一个相同key值的情形。

错误点:不理解字典的定义导致的错误
我们都知道字典中的key是唯一不重复存在,我们在进行添加的时候不能够根据字典的key直接在对应的value上添加people类的对象。

- (void)addPeople:(People *)people
{
    [_dictionary setObject:people forKey:people.group];
    NSLog(@"===============添加成功===============");
}

很显然这样做的后果就是:在可变字典中后面一个相同的key值后覆盖前面一个相同key的value。

下面这种做法是优化之后的,传入什么姓名分组再在字典中开辟对应的键值对

- (void)addPeople:(People *)people
{
    BOOL ishave = NO;
    if (people.name != nil && people.telephone != nil)
    {
        
        for (NSString *k in _dictionary) {
            if (k == people.group) {
                NSMutableArray *p = [NSMutableArray array];
                p = [_dictionary objectForKey:k];
                [p addObject:people];
                ishave = YES;
            }
        }
        
      if (!ishave) {
          NSMutableArray *p = [NSMutableArray array];
      [_dictionary setObject: p  forKey: people.group];
            [p addObject:people];
        }
        NSLog(@"===========添加联系人成功=============");
    }else
    {
        NSLog(@"===========添加联系人失败=============");
    }
}

这片代码首先我们先判断联系人的name和telephone是否为空,如果为空,直接打印失败。

其次,我们要对可变字典中的key进行遍历,如果key中有和联系人分组(首字母)相同时,我们只需要将people类的对象直接添加到对应的value里面。

不然,我们需要创建一个可变数组用来对应不存在的分组,然后将这个对象添加到可变数组中。

但是,我发现在下面对分组里面的姓名进行排序时,我用点语法调用name竟然系统提示我没有声明name的属性。附上图:

ios 字典key iOS 字典里key相同_数组

ios 字典key iOS 字典里key相同_点语法_02

ios 字典key iOS 字典里key相同_首字母_03

报的错提示是:Property ‘name’ not found on object of type ‘id’ ## 标题 ##
更正说明:
上述问题解决方案:如果需要使用点语法,需要将数组中的元素强装成People类型就直接使用name属性了