ObjectiveC程序设计.docx
- 文档编号:9874054
- 上传时间:2023-05-21
- 格式:DOCX
- 页数:15
- 大小:583.66KB
ObjectiveC程序设计.docx
《ObjectiveC程序设计.docx》由会员分享,可在线阅读,更多相关《ObjectiveC程序设计.docx(15页珍藏版)》请在冰点文库上搜索。
ObjectiveC程序设计
Objective-C程序设计
一、Objective-C简介
历史
Brad在20世纪80年代早期设计了Objective-C语言,它以一种叫做SmallTalk-80的语言为基础。
Objective-C在C语言的基础上又加了一层,这意味着对C进行了扩展,从而创造出一门新的程序设计语言,支持对象的创建和操作。
1988年,NeXT计算机公司获得了Objective-C语言的授权,并发展了Objective-C的语言库和一个开发环境,即NEXTSTEP。
1992年,自由软件基金会的GNU开发环境增加了对Objective-C的支持。
所有FreeSoftwareFoundation(FSF)产品的版权归FSF所有。
它以GNU通用公共许可证来发布产品。
1994年,NeXT计算机公司和Sun公司联合发布了一个针对NEXTSTEP系统的标准规范,名为OPENSTEP。
OPENSTEP在自由软件基金会的实现名称为GNUStep。
有一个Linux版本,它包括Linux内核和GNUStep开发环境,这个Linux发行版被十分贴切地命名为LinuxSTEP。
1996年12月20日,苹果公司宣布收购NeXT软件公司,NEXTSTEP/OPENSTEP环境将成为苹果操作系统下一个主要发行版本OSX的基础。
这个开发环境的版本被苹果公司称为Cocoa。
它内置了对Objective-C语言的支持,并结合了ProjectBuilder(后继版本为Xcode)和InterfaceBuilder等开发工具,苹果公司为MacOSX上的应用程序开发创建了一个功能强大的开发环境。
2007年,苹果公司发布了Objective-C语言的升级版,并称之为Objective-C。
第一个Objective-C程序
Objective-C是非常实用的语言。
它是一个用C写成很小的运行库,令应用程序的尺寸增加很小,和大部分OO系统使用极大的VM执行时间会取代了整个系统的运作相反。
Objective-C写成的程序通常不会比其原始码大很多。
Objective-C完全兼容标准C语言,而在此基础上增加了面向对象编程语言的特性以及Smalltalk消息机制。
开发工具:
Xcode下载地址:
实例代码:
#import
intmain(intargc,constchar*argv[])
{
@autoreleasepool{
NSLog(@"HelloWorld!
");
}
return0;
}
Objective-C源文件使用.m作为文件的扩展名。
表列出了常见的文件扩展名。
表
代码解释:
(1)注释:
。
将接口和实现的部分分别放入两个文件,编译器会单独编译每个文件。
要使用该类,只需导入接口文件即可。
当编译器处理包含实现部分的文件时,需要接口部分的信息,因此需要导入.h文件。
要把包含main函数的文件名保存为,作为程序的入口。
合成存取方法
从Objective-C开始,可自动生成设值方法和取值方法(统称为存取方法)。
首先,在接口部分使用@property指令标识属性。
这些属性的命名与实例变量相同。
然后,在实现部分使用@synthesize指令。
例如,接口部分有如下代码,
@interfaceFraction:
NSObject
@propertyintnumerator,denominator;
-(void)print;
-(double)convertToNum;
@end
#import""
在实现部分,没有包含下列设值和取值方法的定义:
numerator、denominator、setNumber:
和setDenominator。
使用@synthesize指令让编译器自动生成或合成这些方法。
@implementationFraction
@synthesizenumerator,denominator;
-(void)print
{
NSLog(@"%i/%i",numerator,denominator);
}
-(double)convertToNum
{
if(denominator!
=0)
return(double)numerator/denominator;
else
returnNAN;
}
@end
使用点运算符访问属性
Objective-C语言允许使用点运算符获取所需值。
例如,等价于[myFractionnumerator],还可以使用点运算符进行赋值,例如=1等价于[myFractionsetNumerator:
1]。
具有多个参数的方法
通过列出每个连续的参数并用冒号将其连接起来,就可以定义一个接收多个参数的方法。
用冒号连接的参数将成为这个方法名的一部分。
例如,在接口文件中添加setTo:
over:
声明,
#import
.
}
@catch(NSException*exception){
statement
statement
...
}
七、分类和协议
分类与扩展
有时候在面对一个类定义时,可能想要添加一些新方法。
例如,对于Fraction类,除了将两个分数相加的add:
方法之外,还想要将两个分数相减、相乘、相除的方法。
分类提供了一种简单的方式,用它可以将类的定义模块化到相关方法的组或分类中。
它还提供了扩展现有类定义的简便方式,并且不必访问类的源代码,也无须创建子类。
例如,
#import
.>)内列出协议名称,可以告知编译器你正在采用一个协议。
例如
@interfaceAddressBook:
NSObject
这说明,AddressBook是父类为NSObject的对象。
并且它遵守NSCopying协议,必须要在实现部分定义它们。
可以使用conformsToProtocol:
方法检查一个对象是否遵循某项协议。
例如,如果有一个名为currentObject的对象,并且想要查看它是否遵循Drawing协议,代码如下,
idcurrentObejct;
if([currentObjectconformsToProtocol:
@protocol(Drawing)]==YES){
//执行协议中的方法
}
定义了协议的类可以看做是将协议定义的方法代理给了实现它们的类。
这样,类的定义可以更为通用,因为具体的动作有代理类来承担,响应某些事件或者定义某些参数。
例如,当你在iPhone上建立一个表格时,会使用到UITableView类。
但是这个类不清楚表格的标题是什么,需要包含多少个区块或是包含多少行,填充表格的内容是什么。
所以代理为你定义了一个UITableViewDataSource协议。
如果它需要消息,比如表格中的每个区块有多少行,它就会调用类中实现协议的相关方法。
UITableView类还定义了其他的协议,如UITableViewDelegate。
协议中还定义了一些方法,如表格中某些行被选中需要怎么样。
八、Foundation框架
Foundation简介
框架是由许多类、方法、函数和文档按照一定的逻辑组织起来的集合,以便使程序开发变得更容易。
在MacOSX系统下大约有90多个框架,这些框架可以用来开发应用程序,处理Mac的AddressBook结构、播放DVD、使用QuickTime播放电影等。
为所有的应用程序开发奠定基础的框架称为Foundation框架,它允许使用一些基本对象,如数字和字符串,以及一些对象集合,如数组、字典和集合。
还包括处理日期和时间、自动化的内存管理、处理基础文件系统、存储对象、处理几何数据结构。
ApplicationKit框架包含广泛的类和方法,它们用来开发交互式图形应用程序,使得开发文本、菜单、工具栏、表、文档和窗口之类的过程变得十分方便。
在MacOSX系统中,术语Cocoa指的是Foundation框架、ApplicationKit框架和名为CoreData的第三方框架。
术语CocoaTouch指的是Foundation、CoreDate、UIKit框架。
数字对象、字符串、集合
数字对象(NSNumber)
int型、float型和long型都是Objective-C语言中的基本数据类型。
不能够向
它们发送消息。
如果需要存储基本数据类型,可以使用NSNumber类,它会根据
这些数据的类型创建对象。
例如,
#import
intmain(intargc,char*argv[])
{
@autoreleasepool{
NSNumber*myNumber,*floatNumber,*intNumber;
NSIntegermyInt;
//integer型值
intNumber=[NSNumbernumberWithInteger:
100];
myInt=[intNumberintegerValue];
NSLog(@"%li",myInt);
//long型值
myNumber=[NSNumbernumberWithLong:
0xabcdef];
NSLog(@"%lx",[myNumberlongValue]);
//char型值
myNumber=[NSNumbernumberWithChar:
'X'];
NSLog(@"%c",[myNumbercharValue]);
//float型值
myNumber=[NSNumbernumberWithFloat:
];
NSLog(@"%g",[myNumberfloatValue]);
//验证两个Number是否相等
if([intNumberisEqualToNumber:
floatNumber]==YES)
NSLog(@"Numbersareequal");
else
NSLog(@"Numbersarenotequal");
//验证一个number是否小于或大于另一个numger
if([intNumbercompare:
myNumber]==NSOrderedAscending)
NSLog(@"Firstnumberislessthansecond");
}
return0;
}
对于每种基本数据类型,类方法都能为它创建一个NSNumber对象,并设置为指定的值。
这些方法以numberWith开头,紧接数据的类型,如numberWithLong、numberWithFloat等,下表列出了NSNumber对象设值的类和实例方法,以及获取这些值相应的实例方法。
表NSNumber的创建和检索方法
字符串对象(NSString)
Foundation框架支持一个名为NSString的类,用于处理字符串对象,使用这个类的方法更容易开发出具有本地化的应用程序,能够在世界上不同的语言环境下使用。
要使用Objective-C语言创建一个常量字符串对象,需要在字符串开头设置一个@字符,例如,
#import
intmain(intargc,char*argv[])
{
@autoreleasepool{
NSString*str=@"Programmingisfun";
NSLog(@"%@",str);
}
return0;
}
可以使用格式化字符%@显示数组、字典和集合全部内容。
事实上,通过覆盖继承的description方法,这可使用这些格式字符显示自己的类对象。
如果不覆盖方法,NSLog仅仅显示类名和该对象在内存中的地址,这是从NSObject类继承的description方法的默认实现。
NSString类中提供了一些方法,如获取字符串长度[str1length]、将一个字符串复制到另一个字符串[NSStringstringWithString:
str1]、验证两个字符串是否相等[str1isEqualToString:
res]等等。
NSString中的常用方法如下表所示,
表NSString中的处理方法
NSString类处理的是不可变字符串,经常需要处理字符串并更改字符串中的字符,这种类型的字符串使用NSMutableString类处理。
例如,
#import
intmain(intargc,char*argv[])
{
autoreleasepool{
NSString*str1=@"ThisisstringA";
NSString*search,*replace;
NSMutableString*mstr;
NSRangesubstr;
//从不可变字符串创建可变字符串
mstr=[NSMutableStringstringWithString:
str1];
NSLog(@"%@",mstr);
//插入字符
[mstrinsertString:
@"mutable"atIndex:
7];
NSLog(@"%@",mstr);
//插入末尾进行拼接
[mstrinsertString:
@"andstringB"atIndex:
[mstrlength]];
NSLog(@"%@",mstr);
//根据范围删除子字符串
[mstrdeleteCharactersInRange:
NSMakeRange(16,13)];
NSLog(@"%@",mstr);
………
}}
字典对象(NSMutableDictionary)
词典(dictionary)是由键-对象对组成的数据集合。
与在词典中查找单词定义一样,可以通过对象的键从Objective-C词典中获取需要的值。
词典中的键必须是单值的,可以是字符串,也可以是其他对象类型。
和键关联的值可以是任何对象类型。
例如,
#import
intmain(intargc,char*argv[])
{
NSMutableDictionary*glossary=[NSMutableDictionarydictionary];
//存储三个条目在类别中
[glossarysetObject:
@"Aclassdefinedsootherclassescaninheritfromit"forKey:
@"abstractclass"];
[glossarysetObject:
@"Toimplementallthemethodsdefinedinaprotocol"forKey:
@"adopt"];
[glossarysetObject:
@"Storinganobjectforlateruse"forKey:
@"abstractclass"];
//检索并显示
NSLog(@"abstractclass:
%@",[glossaryobjectForKey:
@"abstractclass"]);
NSLog(@"adopt:
%@",[glossaryobjectForKey:
@"adopt"]);
NSLog(@"archiving:
%@",[glossaryobjectForKey:
@"archiving"]);
}
return0;
}
集合对象(NSSet、NSMutableSet、NSIndexSet)
set是一组单值对象集合,可以是可变的,也可以是不可变的。
操作包括:
搜索、添加、删除集合中的成员,比较两个集合、计算两个集合的交集和并集等。
主要有三个类NSSet、NSMutableSet、NSIndexSet。
常用的集合方法如下表所示,
九、内存管理和自动引用计数
Objective-C会通过类对象发送alloc消息生成实例对象,alloc的作用就是分配内存。
生成的实例对象用完之后如果不被释放的话,就会发生内存泄漏。
Objective-C提供了一种动态的内存管理方式,称为引用计数。
这种方式会跟踪每个对象被引用的次数,当对象引用的次数为0时,系统就会释放这个对象所占用的内存。
这种内存管理方式称为基于引用计数的内存管理。
还有一种称为自动引用计数的内存管理(ARC)。
自动引用计数使开发者不需要考虑何时使用retain、release、autorelease管理内存,它提供了自动评估对象生存期的功能,在编译期间会自动加入合适的管理内存的方法。
除了ARC之外,还引入了另外一种自动内存管理机制—垃圾回收。
除了垃圾回收时,就不再需要通过引用计数来管理创建的对象,系统会自动识别哪些对象仍在使用,哪些对象可以回收。
手动引用计数内存管理
Objective-C使用了一种叫作引用计数的技术来管理对象所占用的内存。
每个对象都有一个与之相关的整数,称作它的引用计数。
当某段代码不在使用这个对象时,则将对象的引用计数器值减1。
也就是说,引用计数器就是指程序中到底有多少个地方需要访问这个对象。
例如,
使用alloc和初始化方法创建一个对象时,该对象的引用计数器的初始值为1。
假设有一个类A在进行处理的过程中需要使用到实例B,为了防止实例B被别的对象随意释放,类A会事先给实例B发送一个retain消息。
这样,每执行一次retain,实例B的引用计数就会加1。
反之,不再需要某个对象时,可以通过发送release消息,使对象的引用计数减1。
也就是说,当对象的引用计数值达到0的时候,系统就知道这个对象不再需要了。
这时,Objective-C会自动向对象发送一条dealloc消息来释放缓存。
在实际编程的时候,我们会遇到很多只用了一次就不再使用的对象。
如果这种对象也需要逐个释放,那将会很麻烦。
Objective-C提供了一种对象自动释放机制,这种机制的基本思想是把所有需要发送release消息的对象都记录下来,等到需要释放对象时,会给这些对象一起发送release消息。
其中,类NSAutoreleasePool(自动释放池)就起到了记录的作用。
Objective-C还提供了一种创建临时对象的方法,这种方法创建的对象都是临时对象,生成之后会被直接加入内部的自动释放池,必须要关心如何销毁。
例如,-(id)initWithUTF8String:
(constchar*)bytes//生成的实例对象的初始化方法,生成的实例对象的初始引数为1。
+(id)stringWithUTF8String:
(constchar*)bytes//生成临时变量的类方法,生成的实例对象会被自动加入到自动释放池中。
自动引用计数内存管理
ARC(AutoReferenceCounting)是一个编译期技术,利用此技术可以简化Objective-C在内存管理方面的工作量。
ARC通过在编译期间添加合适的retain/release/autorelease等函数,来确保对象被正确地释放。
编译器会根据传入的变量是局部变量还是引用变量,返回对象的方法是不是初始化方法(initialize)等信息来推断应该在何处加入retain/release/autorelease等函数。
这样一来,程序员就可以不再关心是否通过retain或release正确地释放了每个使用的对象,而将更多的精力用于开发程序的核心功能。
例如,现在有一个指向某个对象的变量s,假设将一个w对象赋值给s。
s=w;赋值操作之后,s原来指向的对象将不能通过s来访问,s需要放弃该对象的所有权。
与此同时,s需要获得新赋值对象的w的所有权。
编译以上代码的时候,ARC相当于生成了如下代码:
[wretain];//获得w的所有权
id_old=s;//_old用于临时缓存s
s=w;//赋值之后,s放弃原来对象的所有权
[id_oldrelease];//要考虑到对象的释放再次涉及s的情况
ARC内存管理往往存在循环引用的问题,例如,类A和类B相互引用,要想把A和B都释放掉,按照规则,只有等到释放B之后才可能释放A,同样,只有在释放A之后才能释放B,当双方都在等待对方释放的时候,就形成了循环引用,结果两个对象都不会被释放,这样就会造成内存泄漏。
为了避免循环引用的出现,引入了另外一种类型的变量,这种变量能够引用对象,但不会成为对象所有者,不影响对象本身的回收。
称之为弱引用(weakreference),弱引用通过存储一个指向对象的指针创建,且不保留对象。
Objective-C使用__weak修饰符来定义弱引用,如下例所示,
__weakidtemp;
__weakNSObject*cacheObj;
通常声明的未加__weak修饰符的变量都是强引用类型的变量,声明时也可以通过加上__strong修饰符来明示变量是强引用类型。
垃圾回收
垃圾回收(garbagecollection)指的是在程序运行过程中不定时地检查是否有不再使用的对象,如果存在就释放它所占用的内存空间。
需要注意的是,垃圾回收是MacOSXLeopard之后开始引入的内存管理方法,IOS目前还不支持垃圾回收机制。
MacOSX和IOS5以上的系统强烈推荐使用ARC来管理内存,垃圾回收仅仅是作为一种备选方案存在。
内存的检查和回收都是由垃圾收集器完成。
MacOSX中垃圾回收的目标是不再使用的实例对象。
C风格的变量、C风格的结构体以及C风格申请的内存都不属于垃圾回收的范围。
垃圾回收首先进行的工作就是识别不允许被回收的对象。
首先,全局变量和静态变量引用的对象不允许被回收。
另外,栈内临时变量引用的对象也不允许被回收。
这些称为根集合。
如果一个对象的实例变量引用了不允许被回收的对象或根集合中的对象,那么这个对象也不允许被回收。
垃圾收集器的运行时自适应的,既不以固定的频率运行,也不能通过程序调用运行。
当程序运行过程中超过一定量时,垃圾收集器就会被自动触发运行。
垃圾收集器通常作为一个单独的线程运行,并对已经不再被使用的对象进行回收。
整个回收过程完全是根据占用内存的多少自动完成。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- ObjectiveC 程序设计