码迷,mamicode.com
首页 > 其他好文 > 详细

用OC实现实现中等难度通讯录详解

时间:2015-11-24 22:52:44      阅读:282      评论:0      收藏:0      [点我收藏+]

标签:

用OC实现中等难度通讯录。需求:

     1、定义联系人类Contact。实例变量:姓名(拼音,?字?大写)、性别、电话号码、 住址、分组名称、年龄。?法:?定义初始化方法或便利构造器方法、显?联系人信息

     2、在main.m中定义字典,分组管理所有联系人。分组名为26个大写的英文字母。

     3、可以添加联系?对象,如果姓名或电话号码为空,添加失败。添加联系?到匹配的分组。

     4、获取某个分组名称下所有联系人,并且按照姓名升序排列。

     5、从通讯录中根据电话号码搜索联系人。

     6、获取所有?性的联系人,并且按照年龄的降序排列。

     7、根据姓名删除某个联系人。

     8、删除某个分组的全部联系人。

 

Contact.h的声明部分:

1、在Contact.h文件中实例变量:姓名、性别、电话号码、住址、分组名称, 年龄. 方法:自定义初始化方法或便利构造器方法、显示联系人信息.

 1 @interface Contact : NSObject
 2 {
 3     NSString *_name;
 4     NSString *_gender;
 5     NSString *_phoneNumber;
 6     NSString *_address;
 7     NSString *_groupName;
 8     NSInteger _age;
 9 }
10 
11 // 实例变量的setter和getter方法
12 - (void)setName:(NSString *)name;
13 - (NSString *)name;
14 
15 - (void)setGender:(NSString *)gender;
16 - (NSString *)gender;
17 
18 - (void)setPhoneNumber:(NSString *)phoneNumber;
19 - (NSString *)phoneNumber;
20 
21 - (void)setAddress:(NSString *)address;
22 - (NSString *)address;
23 
24 - (void)setGroupName:(NSString *)groupName;
25 - (NSString *)groupName;
26 
27 - (void)setAge:(NSInteger)age;
28 - (NSInteger)age;
29 
30 // 自定义初始化方法
31 - (id)initWithName:(NSString *)name gender:(NSString *)gender phoneNumber:(NSString *)phoneNumber address:(NSString *)address groupName:(NSString *)groupName age:(NSInteger)age;
32 
33 // 遍历构造器方法
34 + (id)contactWithName:(NSString *)name gender:(NSString *)gender phoneNumber:(NSString *)phoneNumber address:(NSString *)address groupName:(NSString *)groupName age:(NSInteger)age;
35 
36 @end

2.Contact.m实现文件代码

 1 @implementation Contact
 2 // 自定义初始化方法
 3 - (id)initWithName:(NSString *)name gender:(NSString *)gender phoneNumber:(NSString *)phoneNumber address:(NSString *)address groupName:(NSString *)groupName age:(NSInteger)age {
 4     
 5     // 判断父类有没有完全初始化
 6     if (self = [super init]) {
 7         _name = name;
 8         _gender = gender;
 9         _phoneNumber = phoneNumber;
10         _address = address;
11         _groupName = groupName;
12         _age = age;
13     }
14     return self;
15 }
16 
17 
18 // 遍历构造器方法
19 + (id)contactWithName:(NSString *)name gender:(NSString *)gender phoneNumber:(NSString *)phoneNumber address:(NSString *)address groupName:(NSString *)groupName age:(NSInteger)age {
20     
21     return [[Contact alloc] initWithName:name gender:gender phoneNumber:phoneNumber address:address groupName:groupName age:age];
22 }
23 
24 
25 - (void)setName:(NSString *)name {
26     _name = name;
27 }
28 - (NSString *)name {
29     return _name;
30 }
31 
32 - (void)setGender:(NSString *)gender {
33     _gender = gender;
34 }
35 - (NSString *)gender {
36     return _gender;
37 }
38 
39 - (void)setPhoneNumber:(NSString *)phoneNumber {
40     _phoneNumber = phoneNumber;
41 }
42 - (NSString *)phoneNumber {
43     return _phoneNumber;
44 }
45 
46 - (void)setAddress:(NSString *)address {
47     _address = address;
48 }
49 - (NSString *)address {
50     return _address;
51 }
52 
53 - (void)setGroupName:(NSString *)groupName {
54     _groupName = groupName;
55 }
56 - (NSString *)groupName {
57     return _groupName;
58 }
59 
60 - (void)setAge:(NSInteger)age {
61     _age = age;
62 }
63 - (NSInteger)age {
64     return _age;
65 }
66 
67 
68 // 重写description方法(这个方法在无需声明,程序运行时,系统会自动走这个方法)
69 - (NSString *)description
70 {
71     return [NSString stringWithFormat:@"%@ - %@ - %@ - %@ - %@ - %ld", _name, _gender, _phoneNumber, _address, _groupName, _age];
72 }
73 
74 @end

3.创建AddressBook并定义实例变量_manger来管理通讯录的联系人

AddressBook.h文件

 1 #import <Foundation/Foundation.h>
 2 @class Contact;  //注意:在使用前需要在AddressBook.h文件中用@class引入Contact
 3 
 4 @interface AddressBook : NSObject
 5 {
 6   
 7     NSMutableDictionary *_manger;
 8 }
 9 
10 - (void)setManger:(NSMutableDictionary *)manger;
11 - (NSMutableDictionary *)manger;
12 
13 // 添加联系人的方法
14 - (void)addContact:(Contact *)contact;
15 
16 // 展示所有联系人信息的方法
17 - (void)showAllContact;
18 
19 // 获取某个分组下所有的联系人,并按姓名升序
20 - (NSMutableArray *)getAllContactByGroupName:(NSString *)groupName;
21 
22 // 根据电话号码查找联系人
23 - (Contact *)findContactByPhoneNumber:(NSString *)phoneNumber;
24 
25 // 根据性别获取联系人,并按年龄排序
26 - (NSMutableArray *)getAllContactByGender:(NSString *)gender;
27 
28 // 根据姓名删除联系人的方法
29 - (void)removeContactByName:(NSString *)name;
30 
31 // 删除某个分组全部联系人
32 - (void)removeContactByGroupName:(NSString *)groupName;
33 
34 @end

 

下面,就是各个方法的实现了,且看AddressBook.m文件

  1 #import "AddressBook.h"
  2 #import "Contact.h"
  3 @implementation AddressBook
  4 
  5 - (instancetype)init
  6 {
  7     self = [super init];
  8     if (self) {
  9         // 初始化字典
 10         _manger = [NSMutableDictionary dictionaryWithCapacity:0];
 11     }
 12     return self;
 13 }
 14 
 15 
 16 // _manger的setter和getter方法
 17 - (void)setManger:(NSMutableDictionary *)manger {
 18     _manger = manger;
 19 }
 20 - (NSMutableDictionary *)manger {
 21     return _manger;
 22 }
 23 
 24 
 25 // 添加联系人的方法
 26 - (void)addContact:(Contact *)contact {
 27 
 28     //如果姓名或电话号码为空,添加失败
 29     if (0 == contact.name.length || 0 == contact.phoneNumber.length || nil == contact.name || nil == contact.phoneNumber) {
 30         NSLog(@"姓名或电话号码为空,添加失败!请重新输入");
 31         return;
 32     }else{
 33         
 34         // 否则,可以添加联系人到分组.首先取出字典中key值对应的数组(也就是取出分组名构成的数组)
 35         NSMutableArray *group = [_manger objectForKey:contact.groupName];
 36         
 37         // 如果group为空,说明key值不存在,也就是说此时字典中没有分组名.则初始化数组,并添加联系人
 38         if (nil == group) {
 39             group = [NSMutableArray arrayWithCapacity:0]; // 初始化
 40             [group addObject:contact];  // 将联系人添加到group中
 41         }else{      // 如果group不为空,说明key值存在,有这个分组.则直接添加联系人到该分组
 42             [group addObject:contact];
 43         }
 44         
 45         // 修改字典中的键值对(由于新增了联系人,所以要修改字典的键值对)
 46         [_manger setObject:group forKey:contact.groupName];
 47     }
 48 }
 49 
 50 
 51 // 展示所有联系人信息的方法
 52 - (void)showAllContact {
 53     
 54     for (NSString *key in _manger) {
 55         NSString *value = [_manger objectForKey:key];
 56         NSLog(@"%@ = %@", key, value);
 57     }
 58 }
 59 
 60 
 61 // 获取某个分组下所有的联系人,并按姓名升序
 62 - (NSMutableArray *)getAllContactByGroupName:(NSString *)groupName {
 63 
 64     // 根据key值返回key值对应的value值,也就是将根据传入的分组名将该分组中所有的联系人保存到一个数组中
 65     NSMutableArray *group = [_manger objectForKey:groupName];
 66     
 67     // 如果group为空,说明分组不存在
 68     if (group == nil) {
 69         NSLog(@"提示:您搜索的分组不存在");
 70         return nil;
 71     }
 72     
 73     // 如果该分组存在,那么就对group里面的联系人按姓名排序
 74     NSInteger count = group.count;  // 用双层for循环需要知道group的个数
 75     
 76     for (int i = 0; i < count - 1; i++) {
 77         for (int j = 0; j < count - i - 1; j++) {
 78             
 79             // 由于数组名加下标不能点出人的name属性,需要将group[j] group[j + 1]取出来用Contact对象进行操作
 80             Contact *p1 = group[j];
 81             Contact *p2 = group[j  + 1];
 82             
 83             if ([p1.name compare:p2.name] == NSOrderedDescending) {
 84                 // 如果p1.name比p2.name大,则交换位置
 85                 [group exchangeObjectAtIndex:j withObjectAtIndex:j + 1];
 86             }
 87         }
 88     }
 89     return group;
 90 }
 91 
 92 
 93 // 根据电话号码查找联系人
 94 - (Contact *)findContactByPhoneNumber:(NSString *)phoneNumber {
 95 
 96     // 首先遍历key值(分组名),取出各分组下对应的联系人信息. 遍历字典,默认的就是遍历key值
 97     for (NSString *key in _manger) {
 98         
 99         NSMutableArray *group = [_manger objectForKey:key];
100         
101         // 再遍历group数组,查找与传入的电话号码相同的联系人,并输出联系人
102         for (Contact *p in group) {
103             
104             if ([p.phoneNumber isEqualToString:phoneNumber]) {
105                 return p;
106             }
107         }
108     }
109     // 如果没有就返回空
110     return nil;
111 }
112 
113 
114 // 根据性别获取联系人,并按年龄排序
115 - (NSMutableArray *)getAllContactByGender:(NSString *)gender {
116 
117     // 定义一个可变数组,用于存储找到的联系人
118     NSMutableArray *genderArray = [NSMutableArray arrayWithCapacity:0];
119     
120     // 先通过遍历key值(遍历分组名),取出各分组下对应的联系人信息
121     for (NSArray *key in _manger) {
122         NSMutableArray *group = [_manger objectForKey:key];
123         
124         // 再遍历group数组,根据联系人的性别判断是否需要添加到genderGroup数组中
125         for (Contact *p in group) {
126             
127             // 将遍历到与传入的性别一致的联系人添加到genderGroup数组中
128             if ([p.gender isEqualToString:gender]) {
129                 [genderArray addObject:p];
130             }
131         }
132     }
133     
134     // 排序
135     // 首先获取数组中元素的个数
136     NSInteger count = genderArray.count;
137     
138     // 根据年龄排序
139     for (int i = 0; i < count - 1; i++) {
140         
141         for (int j = 0; j < count - i - 1; j++) {
142             
143             // 同样滴,数组名加下标不能点出人的姓名,将其取出来用Contact对象操作
144             Contact *p1 = genderArray[j];
145             Contact *p2 = genderArray[j +  1];
146             
147             if (p1.age > p2.age) {
148                 [genderArray exchangeObjectAtIndex:j withObjectAtIndex:j + 1];
149             }
150         }
151     }
152     // 返回排好序的数组
153     return genderArray;
154 }
155 
156 
157 // 根据姓名删除联系人的方法
158 - (void)removeContactByName:(NSString *)name {
159     
160     // 先取出姓名的首字母, 并转为大写,将其全部放到一个数组里面存储
161     NSString *string = [[name substringToIndex:1] capitalizedString];
162     
163     for (int i = 0; i < [[_manger valueForKey:string]count]; i++) {
164         // 遍历存储姓名首字母大写的数组,并判断是否与传入的姓名的首字母是否一致
165         
166         if ([[[[_manger valueForKey:string] objectAtIndex:i]name] isEqualToString:name]) {
167             // 删除坐标为i,姓名为name的对象
168             [[_manger valueForKey:string] removeObjectAtIndex:i];
169         }
170     }
171 }
172 
173 
174 // 删除某个分组全部联系人
175 - (void)removeContactByGroupName:(NSString *)groupName {
176 
177     // 删除了key值对应的value值即可
178     [_manger removeObjectForKey:groupName];
179 }
180 
181 @end

最后,在main函数中=:

1)首先引入头文件

#import "Contact.h"

#import "AddressBook.h"

#import "Color.h"

2)创建几个联系人,依次调用各方法

    // 创建几个联系人对象
    Contact *p1 = [Contact contactWithName:@"ZhangSan" gender:@"men" phoneNumber:@"10086" address:@"NewYork" groupName:@"Z" age:26];
    Contact *p2 = [Contact contactWithName:@"WuYaoYao" gender:@"women" phoneNumber:@"10087" address:@"BeiJing" groupName:@"W" age:27];
    Contact *p3 = [Contact contactWithName:@"ZhengXi" gender:@"women" phoneNumber:@"10088" address:@"ZhengZhou" groupName:@"Z" age:28];
    Contact *p4 = [Contact contactWithName:@"HaoBing" gender:@"men" phoneNumber:@"10089" address:@"KunMing" groupName:@"H" age:22];
    
    // 创建一个AddressBook对象来管理联系人
    AddressBook *addressBook = [[AddressBook alloc] init];
    
    // 调用添加联系人的方法
    [addressBook addContact:p1];
    [addressBook addContact:p2];
    [addressBook addContact:p3];
    [addressBook addContact:p4];
    
    // 调用展示联系人所有信息的方法
    [addressBook showAllContact];
    
    // 调用获取某个分组下所有联系人并按姓名排序的方法
    NSMutableArray *groupNameContact = [addressBook getAllContactByGroupName:@"Z"];
    NSLog(@"%@", groupNameContact);
    
    // 调用根据电话号码获取联系人的方法
    Contact *finder = [addressBook findContactByPhoneNumber:@"10086"];
    NSLog(@"%@", finder);
    
    // 调用根据性别获取联系人并按年龄排序的方法
    NSMutableArray *genderArray = [addressBook getAllContactByGender:@"women"];
    NSLog(@"%@", genderArray);
    
    // 调用根据姓名删除联系人的方法
    [addressBook removeContactByName:@"HaoBing"];
    [addressBook showAllContact];
    
    // 调用删除某个分组下的所有联系人的方法
    [addressBook removeContactByGroupName:@"Z"];
    [addressBook showAllContact];

 以上就是这个题目的全部解析.

此外,为了优化代码,我们在这里引入几个知识点:

1. 在展示联系人信息的时候,我们采用的是forin这种方法来实现.此外,由于所有联系人都放在一个字典里面,我们同样可以采用NSDictionary下的一个方法实现遍历:

 [dic enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {

        <#code#>

    }];

    // 第一个参数 字典中的key值

    // 第二个参数 字典中key值对应的value值

    // 第三个参数 枚举结束的条件

  enumerateKeysAndObjectsUsingBlock方法其实际只有一个参数block:^(id key, id obj, BOOL *stop) ,这个block携带了三个参数,执行这个方法时,会把Dictionary里面的key值和value值每次一组地传递给block,依次遍历dictionary并把里面所有的key值和value值,将其一组一组地展示出来.在这里,我们要展示所有联系人的信息,那么我们同样可以利用这种方法,上代码:

1 // 展示所有联系人的信息
2 - (void)showAllContact {
3 
4     [_manger enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
5         NSLog(@"%@ = %@", key, obj);
6     }];
7 }

再例如:

//定义了这样一个字典,要求遍历字典输出
NSDictionary *dic = @{@"1":@"a", @"2":@"b", @"3":@"c"}; [dic enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { NSLog(@"%@ - %@", key, obj); *stop = YES; }];

不止是字典有这种遍历的方法,NSArrray同样具有类似的遍历方法 

     [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

       code

     }];

    // 第一个参数obj 是枚举得到的数组元素

    // 第二个参数idx 枚举出数组元素的下标

    // 第三个参数 枚举停止的条件

    // 该方法的执行步骤是 枚举取出数组的元素给obj,同时将其对应的下标给 idx ,直到遇到停止条件stop

  值得注意的是:由于这种方法的前面一个参数默认的是 id 类型, 有时候我们在后面可能需要点出obj的实例变量时无法点出来,这就需要我们将 id 类型修改为想要的类型;

  例如:

// 定义一个数组,要求找出@"3"并输出
NSArray *array = @[@"1", @"2", @"3", @"4", @"5"]; [array enumerateObjectsUsingBlock:^(NSString * obj, NSUInteger idx, BOOL * stop) { if ([obj isEqualToString:@"3"]) { NSLog(@"%@ %lu", obj, idx); *stop = YES; // 如果 *stop = YES ,就会提前结束这个快速枚举. *stop默认是NO } }];

 

2.在涉及到排序的题目中,我们通常采用的是双层for循环,这样就需要我们知道数组中元素的count,这里列举一种不需要count的方法:

sortUsingComparator:

    [arr sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {

        code

    }];

    // 参数 obj1 和 obj2 是数组中两个相邻的元素

    // 此方法的排序方式是根据block块中返回值是NSOrderedDescending对应的判断条件的为准,让相邻的两个元素交换位置

 例如:

    NSArray *arr = @[@"2", @"1", @"6", @"8", @"5", @"9", @"3"];
    NSArray *sortArray2 = [arr sortedArrayUsingComparator:^NSComparisonResult(NSString *obj1, NSString *obj2) {
        
        if (obj1.intValue > obj2.intValue) {
            
            return NSOrderedDescending;
            
        }else if(obj1.intValue < obj2.intValue){
            
            return NSOrderedAscending;
            
        }else{
            
            return NSOrderedSame;
        }
    }];
    
    NSLog(@"%@", sortArray2);

file:///Users/lanouhn/Library/Containers/com.tencent.qq/Data/Library/Application%20Support/QQ/Users/1792427320/QQ/Temp.db/1308F9FD-0A97-43F7-87B2-2A264B459012.png

在通讯录练习中,我们用这种方法来实现 获取分组下所有联系人,并按姓名大小排序的功能:

// 获取分组下所有联系人,并按姓名大小排序
- (NSMutableArray *)sortAllContactByGroupName:(NSString *)groupName {

    NSMutableArray *group = [_manger objectForKey:groupName];
    
    if (group == nil) {
        NSLog(@"您搜索的分组下没有联系人");
        return nil;
    }

    [group sortUsingComparator:^NSComparisonResult(Contact *obj1, Contact *obj2) {
        if ([obj1.name compare:obj2.name] == NSOrderedDescending) {
            return NSOrderedDescending;
        }else if([obj1.name compare:obj2.name] == NSOrderedAscending){
            return NSOrderedAscending;
        }else{
            return NSOrderedSame;
        }
    }];
    return group;
}

 

用OC实现实现中等难度通讯录详解

标签:

原文地址:http://www.cnblogs.com/Harbingwang/p/4991040.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!