设置委托 ABPersonViewControllerDelegate,personVc.personViewDelegate=self;
//显示和编辑一个联系人信息
ABPersonViewController *personVc=[[ABPersonViewController alloc]init];
//把联系人信息作为导航栏的根视图,才可以显示编辑按钮和 完成按钮,返回按钮
UINavigationController *nav=[[UINavigationController alloc]initWithRootViewController:personVc];
ABRecordRef person=ABPersonCreate();
//CFString=CFSTR("")类似NSString =@"";直接赋值
ABRecordSetValue(person, kABPersonFirstNameProperty, CFSTR("jun"), NULL);
ABRecordSetValue(person, kABPersonLastNameProperty, CFSTR("ye"), NULL);
personVc.personViewDelegate=self;
personVc.displayedPerson=person;
CFRelease(person);
personVc.allowsEditing=YES;
委托方法:
-(BOOL)personViewController:(ABPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
{
return NO ;//不为默认操作
}
//添加新联系人到通讯录,一般用于通讯录外面的应用,比如说点击某个按钮,直接进入联系人编辑,然后添加到通讯录
ABUnknownPersonViewController *unknown=[[ABUnknownPersonViewController alloc]init];
unknown.displayedPerson=person;
unknown.allowsAddingToAddressBook=YES;//允许添加
//委托方法
-(BOOL)unknownPersonViewController:(ABUnknownPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
{
return NO;
}
//新建联系人,允许用户填入一个新联系人的所有属性,一般是通讯录里面的新建
ABNewPersonViewController *new=[[ABNewPersonViewController alloc]init];
new.newPersonViewDelegate=self;
//委托方法
-(void)newPersonViewController:(ABNewPersonViewController *)newPersonView didCompleteWithNewPerson:(ABRecordRef)person
{
//用于编辑新联系人后做的事件,比如说模态退出,比如说不保存联系人到通讯录
if (person!=NULL) {
ABAddressBookRef adbk=ABAddressBookCreate();
//从数据库中删除新加的联系人
ABAddressBookRemoveRecord(adbk, person, NULL);
CFStringRef name=ABRecordCopyCompositeName(person);
NSLog(@"name%@",name);//对新加的联系人做处理,不一定要保存到通讯录数据库
CFRelease(name);
CFRelease(adbk);
}
}
计算机语言按照层次划分为:机器语言(0/1)、汇编语言(arm、x86、thumb)和高级语言(c++、java、c)。计算机真正执行的“程序流”是机器语言,早期的程序员都是用机器语言编程,后来为方便记忆发明了汇编语言,但仍然需记住很多硬件相关的操作指令,而且代码规模有限,人们又发明了高级语言。高级语言的出现才真正把程序员从千变万化的硬件操作中解脱出来。综上:编程语言越来越“智能”,抽象层次越来越多,生产率会越来越高。
我们的程序(高级语言)要想被计算机执行,就必须通过某种方式转化成机器语言(低级语言),然后打包成可执行目标程序(executable object program)(知道为什么windows的可执行文件都是.exe结尾了吧)。
以linux为例,输入代码:"gcc -o hello hello.c " (-o hello表示生成的可执行文件名称为hello)代码转化过程如下:
整个过程分为4个阶段(预处理、编译、汇编、链接),以代码文件hello.c为例:
#include <stdio.h> #define PI 3.14 int main() { float test = PI; printf("hello world\n"); }
1、预处理:把hello.c(机器无关)源程序中以“#”开头的预处理项,进行包含替换,生成预处理文件"test.i"(机器无关),当然具体工作还不只这些。例如:#include “stdio.h”就是把“stdio.h”文件内容替换到该行位置;“#define PI 3.14”就是把该宏展开,并且去掉这里的宏定义。总体说来就是不对代码进行任何转化,只进行替换和包含工作。验证结果如下:
输入“gcc -E hello.c -o hello.i” //gcc处理源程序,只进行预处理生成hello.i文件
输入“cat hello.i” //显示hello.i文件内容
可以看到,以“#”开头的文件包含指令和宏指令都已经消失,被相应内容替换掉了,其他程序代码没有任何改变,注意:hello.i 仍然是文本文件,与hello.c 基本无异。
注意:可以结合前面C语言宏定义的分析对比理解:玩儿转C语言:宏定义(1)和玩儿转C语言:宏定义(2)
2、编译:根据处理器指令集(x86、mips、51、arm),把经预处理的“test.i”(机器无关)文件转换成汇编文件“test.s”(机器相关)。不同型号的处理器架构不同,造成他们之间的汇编指令集互不兼容,那同样一段高级程序生成的汇编程序就不相同;反过来讲,对于同一种处理器,即便选择的高级语言种类不同(c++、.net),编译也会产生相同的汇编程序。这么做的好处是:把高级语言和汇编语言之间的连线切断,就可以制造出不同类别的“编译程序”,只修改“编译程序”,就可以为不同的高级语言创建合适的编译系统。分层就有这个好处:抽象级别高,容易修改(只要接口一致即可)。验证结果如下:
输入命令“gcc -S hello.i -o hello.s” //把hello.i文件转换成hello.s文件
输入命令“cat hello.s”
可以看到,把与机器无关的代码“hello.i”进行转化,生成了机器相关的汇编文件“hello.s”。注意:“hello.s”仍然是文本文件,可以用vi直接编辑。
3、汇编:把与机器相关的汇编文件“hello.s”(文本文件)转化成机器相关的可执行(内含机器指令,也叫可重定位的目标文件)文件“hello.o”(二进制文件)。二进制文件hello.o基本上就十分接近可执行的机器文件了,但是还不能正常运行,需要经过下一步的“链接操作”才能真正被执行。验证结果如下:
输入“gcc -c hello.s -o hello.o” //把汇编文件转换成目标文件
输入“cat hello.o”
可以看到,这次已经无法用文本编辑器来正常解析出该文件了,因为二进制文件的解析方式不再是单个字节为单位,而是根据自己的规则调整的。
4、链接:把“hello.o”(二进制文件)转化成“hello”(可执行的二进制文件)。前面讲到“hello.o”几乎接近可执行二进制文件了,但仍然缺点什么。看第一幅图,在链接时,加入了printf.o文件,两个文件输出了一个文件。这是因为我们调用了printf库函数,该函数并不是我们自己定义的,而是在系统库中。既然想用这个函数,肯定也需要把这个函数的相关二进制代码也添加进来才行,这里就是做了这个工作。系统自己已经编译好了目标文件,我们只需要进行“链接”,把调用printf函数的地方,强制跳转到printf.o文件中即可,工作完成再跳回来,这就是为什么hello.o目标文件也叫可重定位文件,因为hello.o文件中还有一些执行代码的跳转地址并没有最终敲定。这里只有一个hello.c文件,如果自己定义了多个源文件,文件之间相互调用的话,也会进行这项工作的。
把printf封装成库是有好处的,因为它是二进制文件(见上图)打开时乱码,这样的话别人就不能看到它的源代码,也就无法模仿可以保护知识产权;也能防止随意修改,造成系统错误。
输入“./ hello” //执行该程序,因为linux的权限管理较严格,即便是执行本目录下的程序也需要加上“./”表示本目录,windows不是这样,权限管理相对较松
系统输出:hello,word
总结:这4个步骤下来,才算完成源程序向可执行程序的转化。中间各个步骤的工作在这里只是大致描述了一下,并不代表他们只做这些事情,具体工作还得研究相关编译器才行。
本文中多次提到了“文本文件”和“二进制文件”,关于它们的概念和异同,可以参考上一篇文章:【1.1】系统漫游——信息就是位+上下文
原创文章如下:
点击打开链接
http://www.docin.com/p-424576452.html