菜鸟:IOS 学习:磨难记 (第五天)
2013-01-19 21:16
281 查看
分析开发者指南源码 GI地址
分析通讯录 模块contact 中model 文件
IAddressBook.h IIAddressBook.m
知识重点:
1、数组
不可变
NSArray*array=[[NSArray alloc] init];
对应
int i = {1, 2,3};
可变
NSMutableArray *mutableArray =[[NSMutableArray alloc] init];
对应
int a[10]
= {1};
2、CLASS消息机制 参考文档Cocoa深入检出消息机制
1,首先去该类的方法 cache 中查找,如果找到了就返回它;
2,如果没有找到,就去该类的方法列表中查找。如果在该类的方法列表中找到了,则将 IMP 返回,并将它加入cache中缓存起来。根据最近使用原则,这个方法再次调用的可能性很大,缓存起来可以节省下次调用再次查找的开销。
3,如果在该类的方法列表中没找到对应的 IMP,在通过该类结构中的 super_class指针在其父类结构的方法列表中去查找,直到在某个父类的方法列表中找到对应的IMP,返回它,并加入cache中;
4,如果在自身以及所有父类的方法列表中都没有找到对应的 IMP,则看是不是可以进行动态方法决议;
5,如果动态方法决议没能解决问题,进入消息转发流程
二、分析源码知识重点
1、
ABMultiValueCopyLabelAtIndex 得到手机的多项属性
ABAddressBookCopyLocalizedLabel 得到本地化版本的属性标签
2、CFSTringref 和NSString
CoreFoundation里面的CFStringRef和NSString*是可以直接转换的,两种也都有一个相似的用来直接赋常量的操作。例如:
CFStringRef a = CFSTR("a");
NSString *b = @"b";
CFSTR分配出来的字符串对象是不能自己释放的
b 一个autorelease的对象
3、stringWithString和initWithString
[NSString stringWithString:@""] stringWithString 是类方法,返回一个auto-released的指向NSString的指针,会自动释放,适合临时变量,在一个函数体内部使用
[[NSString alloc] initWithString:@""] initWithString 实例方法,返回一个指向NSString的指针,同时该对象的retain
count为1,需要手动释放
4、stringByReplacingOccurrencesOfString
[s stringByReplacingOccurrencesOfString:@"s"withString:@"x"]; //S替换为X
5、ABRecordCopyValue
(__bridgeNSDate *)ABRecordCopyValue(person, kABPersonModificationDateProperty); //最后一次修改該条记录的时间返回记录数据
6、ABRecordCopyCompositeName 返回名称
7、ABAddressBookGetPersonWithRecordID 返回某个人的记录
8、ABMultiValueCopyValueAtIndex 返回指定位置的多值属性
9、[array addObject:...] : 向可变数组尾部添加数据对象。
[array addObjectsFromArray:..] :向可变数组尾部添加一个数组对象。
10、ABPersonHasImageData //表示某人是否有图片
11、ABPersonCopyImageData //返回某人图片
12、
NSData 主要用于数据缓冲
[UIImage imageWithData:data] 创建图片数据
13、ABPersonRemoveImageData 删除图片数据
14、ABPersonSetImageData 设置新图片数据
15、
stringWithFormat 格式化字符串
[NSString stringWithFormat:@"%@", stringName]
16、ABMultiValueAddValueAndLabel //添加多项值到指定标示
17、ABRecordSetValue //添加记录
18、CFDictionaryCreate //创建一个不变的字典
IIAddressBook.h
IIAddressBook. m
分析通讯录 模块contact 中model 文件
IAddressBook.h IIAddressBook.m
知识重点:
1、数组
不可变
NSArray*array=[[NSArray alloc] init];
对应
int i = {1, 2,3};
可变
NSMutableArray *mutableArray =[[NSMutableArray alloc] init];
对应
int a[10]
= {1};
2、CLASS消息机制 参考文档Cocoa深入检出消息机制
1,首先去该类的方法 cache 中查找,如果找到了就返回它;
2,如果没有找到,就去该类的方法列表中查找。如果在该类的方法列表中找到了,则将 IMP 返回,并将它加入cache中缓存起来。根据最近使用原则,这个方法再次调用的可能性很大,缓存起来可以节省下次调用再次查找的开销。
3,如果在该类的方法列表中没找到对应的 IMP,在通过该类结构中的 super_class指针在其父类结构的方法列表中去查找,直到在某个父类的方法列表中找到对应的IMP,返回它,并加入cache中;
4,如果在自身以及所有父类的方法列表中都没有找到对应的 IMP,则看是不是可以进行动态方法决议;
5,如果动态方法决议没能解决问题,进入消息转发流程
二、分析源码知识重点
1、
ABMultiValueCopyLabelAtIndex 得到手机的多项属性
ABAddressBookCopyLocalizedLabel 得到本地化版本的属性标签
2、CFSTringref 和NSString
CoreFoundation里面的CFStringRef和NSString*是可以直接转换的,两种也都有一个相似的用来直接赋常量的操作。例如:
CFStringRef a = CFSTR("a");
NSString *b = @"b";
CFSTR分配出来的字符串对象是不能自己释放的
b 一个autorelease的对象
3、stringWithString和initWithString
[NSString stringWithString:@""] stringWithString 是类方法,返回一个auto-released的指向NSString的指针,会自动释放,适合临时变量,在一个函数体内部使用
[[NSString alloc] initWithString:@""] initWithString 实例方法,返回一个指向NSString的指针,同时该对象的retain
count为1,需要手动释放
4、stringByReplacingOccurrencesOfString
[s stringByReplacingOccurrencesOfString:@"s"withString:@"x"]; //S替换为X
5、ABRecordCopyValue
(__bridgeNSDate *)ABRecordCopyValue(person, kABPersonModificationDateProperty); //最后一次修改該条记录的时间返回记录数据
6、ABRecordCopyCompositeName 返回名称
7、ABAddressBookGetPersonWithRecordID 返回某个人的记录
8、ABMultiValueCopyValueAtIndex 返回指定位置的多值属性
9、[array addObject:...] : 向可变数组尾部添加数据对象。
[array addObjectsFromArray:..] :向可变数组尾部添加一个数组对象。
10、ABPersonHasImageData //表示某人是否有图片
11、ABPersonCopyImageData //返回某人图片
12、
NSData 主要用于数据缓冲
[UIImage imageWithData:data] 创建图片数据
13、ABPersonRemoveImageData 删除图片数据
14、ABPersonSetImageData 设置新图片数据
15、
stringWithFormat 格式化字符串
[NSString stringWithFormat:@"%@", stringName]
16、ABMultiValueAddValueAndLabel //添加多项值到指定标示
17、ABRecordSetValue //添加记录
18、CFDictionaryCreate //创建一个不变的字典
IIAddressBook.h
#import <Foundation/Foundation.h> #import <AddressBook/AddressBook.h> //地址薄框架提供联系人数据库,通讯数据库等 @interface IIAddressBook : NSObject { } // get label of phone number (e.g. Mobile, Home, etc) /** + 代表类方法 **/ //得到手机数据 ABMultiValueRef 某一个可能有多个字段数值的记录 + (NSString *)getPhoneLabel:(ABMultiValueRef)phones index:(int)index; // get full name of contact 单个人个名称 ABAddressBookRef 某个通讯录 + (NSString *)getFullName:(ABAddressBookRef)addressBook personId:(int)personId; //某个人的名称 ABRecordRef 某一条通讯录记录 + (NSString *)getFullName:(ABRecordRef)person; // get all phone numbers of one contact 手机号码 //获取某联系人全部电话 ABRecordRef 某一条通讯录记录 + (NSArray *)getPhones:(ABRecordRef)person; // get all emails of one contact 邮箱 //获取某联系人全部邮箱 ABRecordRef 某一条通讯录记录 + (NSArray *)getEmails:(ABRecordRef)person; // get image of contact //获取某联系人头像 ABRecordRef 某一条通讯录记录 + (UIImage*)getImageByPerson:(ABRecordRef)person; //获取某联系人小头像 ABRecordRef 某一条通讯录记录 + (UIImage*)getSmallImage:(ABRecordRef)person size:(CGSize)size; //设置某联系人名称 ABRecordRef 某一条通讯录记录 + (NSString*)getShortName:(ABRecordRef)person; /** * 类消息 返回最近修改的时间 * ABRecordID 记录的ID int 类型 **/ + (NSDate*)copyModificationDate:(ABRecordRef)person; // set address into contact //设置某联系人地址 ABRecordID 记录的ID int 类型 + (BOOL)addAddress:(ABRecordRef)person street:(NSString*)street; // set phones into contact //设置某联系人电话 ABRecordID 记录的ID int 类型 + (BOOL)addPhone:(ABRecordRef)person phone:(NSString*)phone; // set image into contact //设置某联系人头像 ABRecordID 记录的ID int 类型 + (BOOL)addImage:(ABRecordRef)person image:(UIImage*)image; //判断某联系人邮箱数据 ABRecordID 记录的ID int 类型 + (NSArray *)getEmailsWithAddressBook:(ABRecordID)personId addressBook:(ABAddressBookRef)addressBook; //判断某联系人电话数据 ABRecordID 记录的ID int 类型 + (NSArray *)getPhonesWithAddressBook:(ABRecordID)personId addressBook:(ABAddressBookRef)addressBook; //判断某联系人是否有电话 ABRecordRef 某一条通讯录记录 + (BOOL)hasPhones:(ABRecordRef)person; //判断某联系人是否有邮箱 ABRecordRef 某一条通讯录记录 + (BOOL)hasEmails:(ABRecordRef)person; @end
IIAddressBook. m
#import "IIAddressBook.h" @implementation IIAddressBook /** * 得到手机数据 * 1、获取手机lable数据 * 2、转化NSString类型 * 3、替换成正常数据,返回 */ // return label, but remove prefix and suffix in "_$!<Mobile>!$_" + (NSString *)getPhoneLabel:(ABMultiValueRef)phones index:(int)index { /** * CFStringRef 赋值常量 *ABMultiValueCopyLabelAtIndex 得到手机的多项属性 ABAddressBookCopyLocalizedLabel 得到本地化版本的属性标签 */ CFStringRef origLabel = ABMultiValueCopyLabelAtIndex(phones, index); CFStringRef localizedLabel = ABAddressBookCopyLocalizedLabel(origLabel); /** *改进版 * CFStringRef localizedLabel = ABAddressBookCopyLocalizedLabel(CFAutoRelease(ABMultiValueCopyLabelAtIndex(phones, index)));; **/ //转换为字符串 NSString* finalLabel = [NSString stringWithString:(__bridge NSString *)localizedLabel]; //替换 finalLabel = [finalLabel stringByReplacingOccurrencesOfString:@"_$!<" withString:@""]; finalLabel = [finalLabel stringByReplacingOccurrencesOfString:@">!$_" withString:@""]; //返回处理完的手机数据 return f 9571 inalLabel; } /** * 返回 最近修改的时间 **/ + (NSDate*)copyModificationDate:(ABRecordRef)person { //最后一次修改該条记录的时间 NSDate* date = (__bridge NSDate *)ABRecordCopyValue(person, kABPersonModificationDateProperty); return date; } /** * 获取某联系人的名称 * 1、获取某个人的记录 * 2、如果存在数据,调用类消息getFullName处理 */ + (NSString *)getFullName:(ABAddressBookRef)addressBook personId:(int)personId { //ABAddressBookGetPersonWithRecordID 返回某个人的记录 ABRecordRef personRef = ABAddressBookGetPersonWithRecordID(addressBook, personId); //如果没有数据,跳出 if (!personRef) return nil; else { //如果有数据,调用类消息处理 return [IIAddressBook getFullName:personRef]; } } /** * 获取某联系人名称 * 1、从某个人的记录提取名称 * 2、如果存在数据,转化字符串后返回 */ + (NSString *)getFullName:(ABRecordRef)person { //ABRecordCopyCompositeName 返回名称 CFStringRef name = ABRecordCopyCompositeName(person); if (name == NULL){ //如果名字为空,跳出 return [NSString stringWithString:@""]; } //转化微字符串 NSString* ret = [NSString stringWithString:(__bridge NSString*)name]; //释放内存 CFRelease(name); //返回名称 return ret; } /** * 获取某联系人全部电话 * 1、取出某个人的记录 * 2、如果存在数据,调用处理电话的类消息getPhones */ + (NSArray *)getPhonesWithAddressBook:(ABRecordID)personId addressBook:(ABAddressBookRef)addressBook { //ABAddressBookGetPersonWithRecordID 返回某个人的记录 ABRecordRef person = ABAddressBookGetPersonWithRecordID(addressBook, personId); if (person){ //有则调用处理电话消息 return [IIAddressBook getPhones:person]; } else { return nil; } } /** * 判断某联系人是否有电话 * 1、调用处理电话消息 getPhones * 2、存在数据,返回YES ,没有返回NO */ // get the first phone number to display + (BOOL)hasPhones:(ABRecordRef)person { //调用处理电话消息 NSArray* phones = [IIAddressBook getPhones:person]; if (phones != nil && [phones count] > 0){ //返回BOOL return YES; } else { return NO; } } /** * 判断某联系人是否有邮箱 * 1、调用处理邮箱消息 getEmails * 2、存在数据,返回YES ,没有返回NO */ + (BOOL)hasEmails:(ABRecordRef)person { NSArray* emails = [IIAddressBook getEmails:person]; if (emails != nil && [emails count] > 0){ return YES; } else { return NO; } } /** * 获取某联系人全部电话 * 1、取出某个人的记录 * 2、如果存在数据,循环把转化后字符串电话数据压入数组 * 3、返回数据 */ + (NSArray *)getPhones:(ABRecordRef)person { //可变数组初始化 NSMutableArray* phoneList = [[NSMutableArray alloc] init]; //读取电话多值 ABMultiValueRef phones = ABRecordCopyValue(person, kABPersonPhoneProperty); if (phones){ //如果数据存在 int count = ABMultiValueGetCount(phones); //返回电话总数 for (CFIndex i = 0; i < count; i++) { //NSString *phoneLabel = (__bridge NSString *)ABMultiValueCopyLabelAtIndex(phones, i); //转化为多个电话数据为字符串 NSString *phoneNumber = (__bridge NSString *)ABMultiValueCopyValueAtIndex(phones, i); //NSLog(@"phone label (%@), number (%@)", phoneLabel, phoneNumber); //电话数据压入数组 addObject 向可变数组尾部添加数据对象 [phoneList addObject:phoneNumber]; } } //释放内存,返回数据 CFRelease(phones); return phoneList; } /** * 获取某联系人全部电话 * 1、取出某个人的记录 * 2、如果存在数据,循环把转化后字符串电话数据压入数组 * 3、返回数据 */ + (NSArray *)getEmailsWithAddressBook:(ABRecordID)personId addressBook:(ABAddressBookRef)addressBook { //返回某个人的记录 ABRecordRef person = ABAddressBookGetPersonWithRecordID(addressBook, personId); if (person){ //存在回调邮箱处理消息 getEmails return [IIAddressBook getEmails:person]; } else { //没有数据跳出 return nil; } } /** * 获取某联系人全部电话 * 1、取出某个人的记录 * 2、如果存在数据,循环把转化后字符串邮箱数据压入数组 * 3、返回数据 */ // can be refactored to the same implementation later + (NSArray *)getEmails:(ABRecordRef)person { //可变数组 NSMutableArray* emailList = [[NSMutableArray alloc] init]; //读取邮箱多值 ABMultiValueRef emails = ABRecordCopyValue(person, kABPersonEmailProperty); if (emails){ //如果有邮箱数据 int emailCount = ABMultiValueGetCount(emails); for (CFIndex i = 0; i < emailCount; i++) { //转化为多个邮箱数据为字符串 NSString *label = (__bridge NSString *)ABMultiValueCopyLabelAtIndex(emails, i); NSString *value = (__bridge NSString *)ABMultiValueCopyValueAtIndex(emails, i); // NSLog(@"email label (%@), number (%@)", label, value); [emailList addObject:value]; } } //释放内存,返回数据 CFRelease(emails); return emailList; } /** * 获取某联系人头像 * 1、初始化图片类型 * 2、判断是否有图片,如果有先读入换缓冲区,在转化微图片类型 * 3、返回图片数据 */ + (UIImage*)getImageByPerson:(ABRecordRef)person { UIImage* image = nil;//初始化图片类型 if (ABPersonHasImageData(person)){ //表示一人是否有图片 //返回图片到缓冲 NSData* data = (__bridge NSData *)ABPersonCopyImageData(person); image = [UIImage imageWithData:data];//转化图片类型 } return image; } /** * 获取某联系人小头像 * 1没完工 */ + (UIImage*)getSmallImage:(ABRecordRef)person size:(CGSize)size { UIImage* image = [IIAddressBook getImageByPerson:person]; if (image != nil){ // resize image //return [image imageByScalingAndCroppingForSize:size]; } return nil; } /** * 设置某联系人名称 * 1、读取名,和姓 * 2、设置姓名完整标示,姓,名完整行处理 * 3、根据标示,组合姓名 */ + (NSString*)getShortName:(ABRecordRef)person { //返回名 NSString* firstName = (__bridge NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty); //返回姓 NSString* lastName = (__bridge NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty); //返回公司 NSString* orgName = (__bridge NSString *)ABRecordCopyValue(person, kABPersonOrganizationProperty); BOOL useOrgName = NO; //姓名是否完整标示 if (firstName == nil && lastName == nil) //如果姓名都有,设置YES useOrgName = YES; if (firstName == nil) // 处理名 firstName = @""; if (lastName == nil) //处理姓 lastName = @""; NSString* fullName; //姓名 if (useOrgName == NO){ //如果姓名完整 NSString* countryCode; //是否多国判断 //NSString* countryCode = [LocaleUtils getCountryCode]; if (countryCode != nil && ( [countryCode isEqualToString:@"CN"] == YES || [countryCode isEqualToString:@"TW"] == YES || [countryCode isEqualToString:@"KR"] == YES || [countryCode isEqualToString:@"JP"] == YES) ) { if ([lastName length] > 0){ //如果姓,名有数据,则把姓,名设置给全名变量 fullName = [NSString stringWithFormat:@"%@ %@", lastName, firstName]; } else { //否则把名设置给全名变量 fullName = [NSString stringWithString:firstName]; } }//默认不区分国际 else { if ([firstName length] > 0){ //如果名有数据,则把名设置给全名变量 fullName = [NSString stringWithFormat:@"%@", firstName]; } else { //否则把姓设置给全名变量 fullName = [NSString stringWithString:lastName]; } } } //如果姓名不完整 else { if (orgName == nil) //标示为空 orgName = @""; //格式化标示 fullName = [NSString stringWithFormat:@"%@", orgName]; } //返回姓名 return fullName; } /** * 设置电话 * 1、初始化一些参数 * 2、添加多项值到指定标示 * 3、添加多条记录 */ + (BOOL)addPhone:(ABRecordRef)person phone:(NSString*)phone { //创建一个新的,空的,可变的多值属性 ABMutableMultiValueRef multi = ABMultiValueCreateMutable(kABMultiStringPropertyType); CFErrorRef anError = NULL; // The multivalue identifier of the new value isn't used in this example, // multivalueIdentifier is just for illustration purposes. Real-world // code can use this identifier to do additional work with this value. ABMultiValueIdentifier multivalueIdentifier;//多项标示符 //添加多项值到指定标示 if (!ABMultiValueAddValueAndLabel(multi, (__bridge CFStringRef)phone, kABPersonPhoneMainLabel, &multivalueIdentifier)){ CFRelease(multi); return NO; } //添加记录 if (!ABRecordSetValue(person, kABPersonPhoneProperty, multi, &anError)){ CFRelease(multi); return NO; } //释放内存,返回BOOL CFRelease(multi); return YES; } /** * 设置地址 * 1、初始化一些参数 * 2、添加多项值到指定标示 * 3、添加多条记录 */ + (BOOL)addAddress:(ABRecordRef)person street:(NSString*)street { //创建一个新的,空的,可变的多值属性 ABMutableMultiValueRef address = ABMultiValueCreateMutable(kABDictionaryPropertyType); static int homeLableValueCount = 5; // Set up keys and values for the dictionary. CFStringRef keys[homeLableValueCount];//键数组 CFStringRef values[homeLableValueCount];//值数组 keys[0] = kABPersonAddressStreetKey; //街道 keys[1] = kABPersonAddressCityKey; //城市标示 keys[2] = kABPersonAddressStateKey;//州 keys[3] = kABPersonAddressZIPKey; //邮编 keys[4] = kABPersonAddressCountryKey; //国家 values[0] = (__bridge CFStringRef)street; values[1] = CFSTR(""); values[2] = CFSTR(""); values[3] = CFSTR(""); values[4] = CFSTR(""); //CFDictionaryCreate 创建一个不变的字典 CFDictionaryRef aDict = CFDictionaryCreate( kCFAllocatorDefault, (void *)keys, (void *)values, homeLableValueCount, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); // Add the street address to the person record. ABMultiValueIdentifier identifier; //标示 //添加多项值到指定标示 BOOL result = ABMultiValueAddValueAndLabel(address, aDict, kABHomeLabel, &identifier); CFErrorRef error = NULL; //添加记录 result = ABRecordSetValue(person, kABPersonAddressProperty, address, &error); //释放内存,返回数据 CFRelease(aDict); CFRelease(address); return result; } /** * 设置某联系人头像 * 1、删除旧图片 * 2、设置新的图片,返回图片数据 */ + (BOOL)addImage:(ABRecordRef)person image:(UIImage*)image { CFErrorRef error = NULL; //错误类型记录 // remove old image data firstly ABPersonRemoveImageData(person, NULL); //删除旧的图片数据 // add new image data 设置新图片数据 BOOL result = ABPersonSetImageData ( person, (__bridge CFDataRef)UIImagePNGRepresentation(image), &error ); // CFRelease(error); return result; } @end
相关文章推荐
- 菜鸟:IOS 学习:磨难记 (第六天)
- 菜鸟:IOS 学习:磨难记 (第四天)
- 菜鸟:IOS 学习:磨难记 (第七天)
- 菜鸟:IOS 学习:磨难记(第一天)
- 菜鸟:IOS 学习:磨难记 (第二天)
- 菜鸟:IOS 学习:磨难记 (第三天)
- IOS开发---菜鸟学习之路--(二十二)-近期感想以及我的IOS学习之路
- ios学习第五天(四)UILabel的使用
- [翻译] 学习iOS开发的建议:如何从菜鸟到专家
- iOS菜鸟学习——UITextField 和 UITextView实现字数限制
- IOS开发---菜鸟学习之路--(十一)-使新闻内容自适应高度
- ios学习第五天(二)给页面中的View添加子View
- iOS菜鸟成长笔记(3)——斯坦福公开课学习(1)
- iOS菜鸟学习——NSSortDescriptor的使用
- iOS菜鸟学习——如何实现Label文本自适应
- IOS开发---菜鸟学习之路--(十七)-利用UITableView实现个人信息界面
- 我的IOS学习历程-第五天
- iOS学习--老菜鸟的storyboard学习之路
- iOS菜鸟成长笔记(3)——斯坦福公开课学习(1)
- iOS学习笔记---oc语言第五天