ObjectiveC程序设计

上传人:沈*** 文档编号:100786516 上传时间:2022-06-03 格式:DOC 页数:30 大小:69.50KB
收藏 版权申诉 举报 下载
ObjectiveC程序设计_第1页
第1页 / 共30页
ObjectiveC程序设计_第2页
第2页 / 共30页
ObjectiveC程序设计_第3页
第3页 / 共30页
资源描述:

《ObjectiveC程序设计》由会员分享,可在线阅读,更多相关《ObjectiveC程序设计(30页珍藏版)》请在装配图网上搜索。

1、-Objective-C程序设计一、 Objective-C简介1.1历史Brad J.Co*在20世纪80年代早期设计了Objective-C语言,它以一种叫做SmallTalk-80的语言为根底。Objective-C在C语言的根底上又加了一层,这意味着对C进展了扩展,从而创造出一门新的程序设计语言,支持对象的创立和操作。1988年,Ne*T计算机公司获得了Objective-C语言的授权,并开展了Objective-C的语言库和一个开发环境,即NE*TSTEP。1992年,自由软件基金会的GNU开发环境增加了对Objective-C的支持。所有Free Software Foundati

2、onFSF产品的归FSF所有。它以GNU通用公共许可证来发布产品。1994年,Ne*T计算机公司和Sun公司联合发布了一个针对NE*TSTEP系统的标准规*,名为OPENSTEP。OPENSTEP在自由软件基金会的实现名称为GNUStep。有一个Linu*版本,它包括Linu*内核和GNUStep开发环境,这个Linu*发行版被十分贴切地命名为Linu*STEP。1996年12月20日,苹果公司宣布收购Ne*T软件公司,NE*TSTEP/OPENSTEP环境将成为苹果操作系统下一个主要发行版本OS *的根底。这个开发环境的版本被苹果公司称为Cocoa。它内置了对Objective-C语言的支持

3、,并结合了Project Builder后继版本为*code和Interface Builder等开发工具,苹果公司为Mac OS *上的应用程序开发创立了一个功能强大的开发环境。2007年,苹果公司发布了Objective-C语言的升级版,并称之为Objective-C 2.0。1.2第一个Objective-C程序Objective-C是非常实用的语言。它是一个用C写成很小的运行库,令应用程序的尺寸增加很小,和大局部OO系统使用极大的VM执行时间会取代了整个系统的运作相反。Objective-C写成的程序通常不会比其原始码大很多。Objective-C完全兼容标准C语言,而在此根底上增加了

4、面向对象编程语言的特性以及Smalltalk消息机制。开发工具:*code 下载地址:developer.apple.实例代码:#import int main(int argc,const char * argv) autoreleasepool NSLog(Hello World!); return 0;Objective-C源文件使用.m作为文件的扩展名。表1.1列出了常见的文件扩展名。表1.1代码解释:1注释:/或/* */2将文件信息导入或者包含到文件中,其中包含其他类和函数的有关信息。3main特殊名称,准确地表示程序在何处执行。4autoreleasepool自动释放池:使得应用

5、在创立对象时,系统能够有效地管理应用所使用的内存。5调用名为NSLog的函数,传递给NSLog函数的参数是字符串:Hello World!符号位于一对双引号的字符串前面,成为NSString对象。NSLog不仅能显示简单短语,还能显示变量的值及计算结果。例如,NSLog(The sum of %i and %i is %i,value1,value2,sum);可以按格式输出变量的值。二、Objective-C程序设计初步2.1根本数据类型和表达式根本数据类型与C+语言根本一样,不同的是,Objective-C添加了一种id类型,id数据类型可存储任何类型的对象,从*种意义上说,它是一般对象类

6、型。id类型是多态和动态绑定的根底。根本数据类型如表2.1所示,表2.1表达式与所有的程序设计语言一样,运算符具有优先级,优先级较高的运算符首先求值。如果优先级一样,可按照从左到右或者从右到左的方向来求值,具体按哪个方向取值取决于运算符。例如常见的算术运算符、逻辑运算符、赋值运算符等等。2.2根本控制构造与大多数程序设计语言相似,包括顺序、选择、循环构造,在此不再累述。三、类、对象与方法入门3.1根本概念对象对象是人们要进展研究的任何事物,从最简单的整数到复杂的飞机等均可看作对象,它不仅能表示具体的事物,还能表示抽象的规则、方案或事件。对象的状态和行为对象具有状态,一个对象用数据值来描述它的状

7、态。对象还有操作,用于改变对象的状态,对象及其操作就是对象的行为。对象实现了数据和操作的结合,使数据和操作封装于对象的统一体中类具有一样特性数据元素和行为功能的对象的抽象就是类。因此,对象的抽象是类,类的具体化就是对象,也可以说类的实例是对象,类实际上就是一种数据类型。类具有属性,它是对象的状态的抽象,用数据构造来描述类的属性。类具有操作,它是对象的行为的抽象,用操作名和实现该操作的方法来描述。类的构造在客观世界中有假设干类,这些类之间有一定的构造关系。通常有两种主要的构造关系,即一般-具体构造关系,整体-局部构造关系。一般-具体构造称为分类构造,也可以说是或关系,或者是is a关系。整体-局

8、部构造称为组装构造,它们之间的关系是一种与关系,或者是has a关系。消息和方法对象之间进展通信的构造叫做消息。在对象的操作中,当一个消息发送给*个对象时,消息包含接收对象去执行*种操作的信息。发送一条消息至少要包括说明承受消息的对象名、发送给该对象的消息名即对象名、方法名。一般还要对参数加以说明,参数可以是认识该消息的对象所知道的变量名,或者是所有对象都知道的全局变量名。类中操作的实现过程叫做方法,一个方法有方法名、返回值、参数、方法体。3.2 Objective-C中的面向对象下面采用面向对象的方法编写一个用于处理分数的程序,代码如下所示,#import /-interface局部-int

9、erface Fraction:NSObject-(void) print-(void) setNumberator:(int) n;-(void) setDenominator:(int) d;end/-implementation局部-implement Fraction int numerator; int denominator;-(void) print NSLog(%i/%i,numerator,denominator);-(void) setNumberator:(int) n numerator=n;-(void) setDenominator:(int) d denomina

10、tor=d;end/-program局部-int main(int argc,char *argv) autoreleasepool Fraction *myFraction; /创立一个分数实例 myFraction = Fraction alloc; myFraction = myFraction init; /设置分数为1/3 myFraction setNumerator:1; myFraction setDenominator:3; /使用打印方法显示分数 NSLog(The value of myFraction is :); myFraction print; return 0;

11、代码解释:interface局部用于描述类和类的方法;implementation局部用于描述数据类对象的实例变量存储的数据,并实现在接口中声明方法的实际代码;program局部实现了程序的预期目的。1interface局部包含两个局部,首先需要告诉Objective-C编译器该类来自何处,也就是说,必须为它的父类命名。其次,必须定义在处理该类的对象时将要用到的各种操作或方法的类型。该局部的一般格式类似于以下语句:interface NewClassName: ParentClassName propertyAndMethodDeclarations;endObjective-C中变量的名称必

12、须以字母或下划线_开头,之后可以是任何字母、下划线或者09之间的数字组合。对于大小写敏感。确定名称时,应该能反映变量或对象使用意图的名称。Objective-C中的方法分为类方法和实例方法,其中,负号-表示是实例方法,正号+表示是类方法。方法的完整定义如图2.1所示,图2.1方法定义2implementation局部implementation局部包含声明在interface局部的方法的实际代码,且需要指定存储在类对象中的数据类型。在interface局部声明方法,并在implementation局部定义它们。implementation局部的一般格式如下:implementation New

13、ClassName memberDeclarations;methodDefinitions;end其中,memberDeclarations局部指定了哪种类型的数据将要存储到Fraction中,以及这些数据类型的名称。在这一局部声明的变量成为实例变量。methodDefinitions局部包含在interface局部指定的每个方法的代码中。每种方法的定义通过方法的类型、返回值和参数进展标识。2.3 program局部program局部包含解决特定问题的代码,必须有一个名为main()的函数作为程序开场的地方。如前段代码所述,通过以下程序行定义了一个名为myFraction的变量:Fracti

14、on *myFraction;这一行表示myFraction是一个Fraction类型的对象*号说明myFraction是Fraction对象的引用,存储了一个内存地址,说明对象数据在内存中的位置。使用myFraction=Fraction alloc init向*个类发送alloc消息获得该类的新实例,alloc保证所有的实例变量都变成初始状态。使用init方法初始化类的实例变量,init方法返回一个值,即被初始化的对象。下一步,程序行myFraction setNumerator:1 将控制转到Fraction类中定义的setNumerator方法,将myFraction的分子设置为1。四

15、、Objective-C中的类4.1别离接口和实现文件通常,将类的声明即interface局部放在它自己的名为class.h文件中。而类的定义即implementation局部通常放在一样名称的文件中,但扩展名为.m。将接口和实现的局部分别放入两个文件,编译器会单独编译每个文件。要使用该类,只需导入接口文件即可。当编译器处理包含实现局部的文件时,需要接口局部的信息,因此需要导入.h文件。要把包含main函数的文件名保存为main.m,作为程序的入口。4.2合成存取方法从Objective-C 2.0开场,可自动生成设值方法和取值方法统称为存取方法。首先,在接口局部使用property指令标识属

16、性。这些属性的命名与实例变量一样。然后,在实现局部使用synthesize指令。例如,接口局部有如下代码,interface Fraction : NSObjectproperty int numerator,denominator;-(void) print;-(double) convertToNum;end#import Fraction.h在实现局部,没有包含以下设值和取值方法的定义:numerator、denominator、setNumber:和setDenominator。使用synthesize指令让编译器自动生成或合成这些方法。implementation Fractions

17、ynthesize numerator,denominator;-(void) print NSLog(%i/%i,numerator,denominator);-(double) convertToNum if(denominator!=0) return (double)numerator/denominator; else return NAN;end4.3使用点运算符访问属性Objective-C语言允许使用点运算符获取所需值。例如,myFraction.numerator等价于myFraction numerator,还可以使用点运算符进展赋值,例如myFraction.numera

18、tor=1等价于myFraction setNumerator: 1。4.4具有多个参数的方法通过列出每个连续的参数并用冒号将其连接起来,就可以定义一个接收多个参数的方法。用冒号连接的参数将成为这个方法名的一局部。例如,在接口文件中添加setTo:over:声明,#import/定义Fraction类interface Fraction :NSObjectproperty int numerator,denominator;-(void) print;-(void) setTo:(int) n over:(int) d;end然后,在实现中添加新方法的定义。#import Fraction.h

19、implementation Fractionsynthesize numerator, denominator;-(void) print NSLog(%i/%i,numerator,denominator);-(void) setTo:(int) n over: (int) d numerator=n; denominator=d;end7.5局部变量、方法参数、静态变量局部变量、方法参数、静态变量与C语言类似,不再累述。需要强调的是,局部变量使用前必须初始化,静态变量会自动初始化。7.6 self关键字关键字self用来指明对象是当前方法的接收者。例如,有如下代码,-(void) add

20、: (Fraction *) f numerator=numerator*f.denominator+denominator*f.numerator; denominator=denominator*f.denominator; self reduce在add:消息中编写self reduce,就可以对Fraction应用reduce方法,它正是add:消息的接收者,执行add:方法时,self是作为Fraction的引用,分数会得到约减。五、继承5.1根类没有父类的类位于类层次构造的最顶层,称为根root类。自定义的类都属于NSObejct根类的派生类。5.2通过继承来扩展与C+、java等

21、面向对象语言相似,Objective-C中定义的父类的非私有实例变量和方法都会称为新类定义的一局部。例如,interface ClassA:NSObject int *;-(void) initVar;endimplementation ClassA-(void) initVar *=100;end定义一个名为ClassB的新类,继承自ClassAinterface ClassB:ClassA-(void) printVar;endimplementation ClassB-(void) printVar NSLog(*=%i,*);end5.3方法覆写与其他面向对象语言类似,在子类中使用和父

22、类一样的名称定义的方法代替或覆写父类中的方法,新方法必须具有一样的返回类型,并且参数的数目要与覆写的方法一样。如果在不同的类中有名称一样的方法,则根据作为消息的接收者的类选择正确的方法。六、多态、动态类型、动态绑定6.1多态多态按字面的意思就是多种状态。在面向对象语言中,接口的多种不同的实现方式即为多态。多态性是允许你将父对象设置成为一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。C+中,实现多态有以下方法:虚函数,抽象类,覆盖,模板。6.2动态绑定和id类型id可以用来存储

23、属于任何类的对象,会导致程序无法区分*个实例对象到底是哪个类的对象。Objective-C总是先判定对象所属的类,然后在运行时确定需要动态调用的方法,而不是在编译时。换句话说,动态绑定指的就是在程序运行时才能确定对象的属性和需要响应的消息。例如,#import Fraction.h#import ple*.hint main(int argc, char *argv) autoreleasepool id dataValue; Fraction *f1=Fraction alloc init; ple* *c1=ple* alloc init; f1 setTo: 2 over 5; c1 s

24、etReal: 10.0 andImaginary: 2.5; /dataValue获得了一个分数 dataValue=f1; dataValue print; /dataValue获得了一个ple*数 dataValue=c1; dataValue print;return 0;当系统将print消息发送给dataValue时,它首先会检查dataValue中存储的对象所属的类。结合多态、动态绑定,可以轻易地编写出可以向不同类的对象发送一样消息的代码。例如,考虑可用来在屏幕上绘制对象的draw方法。你可能为每个图像对象比方文本、圆、矩形、窗口,等等定义了不同的draw方法。如果要绘制的特定对

25、象存储在一个名为currentObject的id变量中,仅仅通过发送draw消息就可以在屏幕上进展绘制,语句如下,currentObject draw。6.3编译时和运行时检查因为存储在id变量中的对象类型在编译时无法确定,所以一些测试会推迟到运行时进展。例如,Fraction *f1=Fraction alloc init;f1 setReal: 10.0 andImaginary: 2.5;当编译此段代码时,将显示以下消息:Fraction may not respond to setReal:andImaginary: 现在考虑下面的代码序列:id dataValue=Fraction

26、alloc init;dataValue setReal:10.0 andImaginary:2.5;这段代码在编译时,编译器并不知道存储在dataValue中的对象类型,直到运行时,会出现如下出错信息:-Fraction setReal:andImaginary:unrecognized selector sent to instance 0*103f00将一个变量定义为特定类的对象时,应尽量使用静态类型。静态指的是对存储在变量中对象的类型进展显式声明。这时候,编译器能够通过检查确定应用于对象的方法是由该类定义的还是由该类继承的,否则将显示警告信息。编译时进展的类型检查的要点如下,(1) 对

27、于id类型的变量,调用任何方法都能够通过编译。(2) Id类型的变量和被定义为特定类的变量之间可以相互赋值。(3) 被定义为特定类对象的变量静态类型如果调用了类或方法中未定义的方法,编译器就会提示警告。(4) 假设是静态类型的变量,子类类型的实例变量可以赋值给父类类型的实例变量。(5) 假设要判断到底是哪个类的方法执行了,不要看变量所声明的类型,而要看实际执行时这个变量的类型。(6) Id类型并不是NSObject*类型。6.4 使用try处理异常在Objective-C中,处理异常情况的语法格式为,try statement statement .catch (NSE*ception *e*

28、ception) statement statement .七、分类和协议7.1分类与扩展有时候在面对一个类定义时,可能想要添加一些新方法。例如,对于Fraction类,除了将两个分数相加的add:方法之外,还想要将两个分数相减、相乘、相除的方法。分类提供了一种简单的方式,用它可以将类的定义模块化到相关方法的组或分类中。它还提供了扩展现有类定义的简便方式,并且不必访问类的源代码,也无须创立子类。例如,#import /定义Fraction类interface Fraction : NSObjectproperty int numerator,denominator;-(void) setTo:

29、(int) n over:(int) d;-(Fraction *) add:(Fraction *)f;-(void) reduce;-(double) convertToNum;-(void) print;end从接口局部删除add:方法,并将其添加到新分类,同时添加其他三种要实现的数学运算。新的MathOps分类的接口局部代码如下:#import Fraction.hinterface Fraction (MathOps)-(Fraction *) add:(Fraction *) f;-(Fraction *) mul:(Fraction *) f;-(Fraction *) sub:

30、(Fraction *) f;-(Fraction *) div:(Fraction *) f;end其中,Fraction(MathOps)表示正在为Fraction类定义新的分类,并且它的名称为MathOps。注意,分类不能添加新的实例变量。创立一个未命名的分类,且在括号()之间不指定名字,这种特殊的语法格式定义称为类的扩展。与分类不同的是,扩展可以添加新的实例变量。注意,未命名分类中的方法都是私有的,如果需要写一个类,而且数据和方法仅供这个类本省使用,未命名分类比拟适宜。例如,#import GraphicObject.h/类的扩展interface GraphicObject()pro

31、perty int uniqueID;-(void) doStuffWithUniqueID:(int) theID;endimplementation GraphicObjectsynthesize uniqueID;-(void) doStuffWithUniqueID:(int) myID self.uniqueID=myID;通过添加一个新的实例变量uniqueID扩展了GraphicObject类,并合成了设值与取值方法。另外,还添加了一个名为doStuffWithUniqueID:的方法。7.2协议与代理协议是多个类共享的一个方法列表。协议表示对象的作用和行为的方法的集合体。在对象

32、模型化的软件世界里,不同的对象也可能包含一样的方法集合,但通常情况下,这些对象之间并不是继承关系。例如,数组、线性表、二分查找树就是这样的集合对象。这些类之间并没有继承关系,但都有添加、删除、升序排序这样的操作。这些操作就是协议。协议中列出的方法没有相应的实现,协议提供了一种方式,可以用指定的名称定义一组方法。这些方法有些是选择实现,有些是必须实现。可以使用命令符required默认,optional用来设定其后出现的方法是可选的还是必选的。定义一个协议很简单,只需使用protocol指令。例如,在头文件NSObject中定义NSCopying协议的方式:protocol NSCopying-

33、(id) copyWithZone: (NSZone *)zone;end如果你的类采用NSCopying协议,则必须实现名为copyWithZone:的方法。通过在interface行的一对尖括号()内列出协议名称,可以告知编译器你正在采用一个协议。例如interface AddressBook:NSObject这说明,AddressBook是父类为NSObject的对象。并且它遵守NSCopying协议,必须要在实现局部定义它们。可以使用conformsToProtocol:方法检查一个对象是否遵循*项协议。例如,如果有一个名为currentObject的对象,并且想要查看它是否遵循Dra

34、wing协议,代码如下,id currentObejct;if(currentObject conformsToProtocol: protocol (Drawing)=YES)/执行协议中的方法定义了协议的类可以看做是将协议定义的方法代理给了实现它们的类。这样,类的定义可以更为通用,因为具体的动作有代理类来承当,响应*些事件或者定义*些参数。例如,当你在iPhone上建立一个表格时,会使用到UITableView类。但是这个类不清楚表格的标题是什么,需要包含多少个区块或是包含多少行,填充表格的内容是什么。所以代理为你定义了一个UITableViewDataSource协议。如果它需要消息,比

35、方表格中的每个区块有多少行,它就会调用类中实现协议的相关方法。UITableView类还定义了其他的协议,如UITableViewDelegate。协议中还定义了一些方法,如表格中*些行被选中需要怎么样。八、Foundation框架8.1 Foundation简介框架是由许多类、方法、函数和文档按照一定的逻辑组织起来的集合,以便使程序开发变得更容易。在Mac OS *系统下大约有90多个框架,这些框架可以用来开发应用程序,处理Mac的Address Book构造、播放DVD、使用QuickTime播放电影等。为所有的应用程序开发奠定根底的框架称为Foundation框架,它允许使用一些根本对象

36、,如数字和字符串,以及一些对象集合,如数组、字典和集合。还包括处理日期和时间、自动化的内存管理、处理根底文件系统、存储对象、处理几何数据构造。Application Kit框架包含广泛的类和方法,它们用来开发交互式图形应用程序,使得开发文本、菜单、工具栏、表、文档和窗口之类的过程变得十分方便。在Mac OS *系统中,术语Cocoa指的是Foundation框架、Application Kit框架和名为Core Data的第三方框架。术语Cocoa Touch指的是Foundation、Core Date、UIKit框架。8.2数字对象、字符串、集合数字对象NSNumberint型、float

37、型和long型都是Objective-C语言中的根本数据类型。不能够向它们发送消息。如果需要存储根本数据类型,可以使用NSNumber类,它会根据这些数据的类型创立对象。例如,#import int main(int argc,char *argv) autoreleasepoolNSNumber *myNumber,*floatNumber,*intNumber;NSInteger myInt; /integer型值intNumber=NSNumber numberWithInteger:100;myInt=intNumber integerValue;NSLog(%li,myInt);/l

38、ong型值myNumber=NSNumber numberWithLong:0*abcdef;NSLog(%l*,myNumber longValue);/char型值myNumber=NSNumber numberWithChar:*;NSLog(%c,myNumber charValue);/float型值myNumber=NSNumber numberWithFloat:100.00;NSLog(%g,myNumber floatValue);/验证两个Number是否相等if(intNumber isEqualToNumber:floatNumber=YES)NSLog(Numbers

39、 are equal);elseNSLog(Numbers are not equal);/验证一个number是否小于或大于另一个numgerif(intNumber pare:myNumber=NSOrderedAscending)NSLog(First number is less than second); return 0;对于每种根本数据类型,类方法都能为它创立一个NSNumber对象,并设置为指定的值。这些方法以numberWith开头,紧接数据的类型,如numberWithLong、numberWithFloat等,下表列出了NSNumber对象设值的类和实例方法,以及获取这些

40、值相应的实例方法。表8.1 NSNumber的创立和检索方法字符串对象NSStringFoundation框架支持一个名为NSString的类,用于处理字符串对象,使用这个类的方法更容易开发出具有本地化的应用程序,能够在世界上不同的语言环境下使用。要使用Objective-C语言创立一个常量字符串对象,需要在字符串开头设置一个字符,例如,#importint main(int argc,char *argv) autoreleasepoolNSString *str=Programming is fun;NSLog(%,str); return 0;可以使用格式化字符%显示数组、字典和集合全部

41、内容。事实上,通过覆盖继承的description方法,这可使用这些格式字符显示自己的类对象。如果不覆盖方法,NSLog仅仅显示类名和该对象在内存中的地址,这是从NSObject类继承的description方法的默认实现。NSString类中提供了一些方法,如获取字符串长度str1 length、将一个字符串复制到另一个字符串NSString stringWithString: str1、验证两个字符串是否相等str1 isEqualToString :res等等。NSString中的常用方法如下表所示,表8.2 NSString中的处理方法NSString类处理的是不可变字符串,经常需要处

42、理字符串并更改字符串中的字符,这种类型的字符串使用NSMutableString类处理。例如,#import int main(int argc,char *argv) autoreleasepool NSString *str1=This is string A; NSString *search,*replace; NSMutableString *mstr; NSRange substr; /从不可变字符串创立可变字符串 mstr=NSMutableString stringWithString: str1; NSLog(%,mstr); /插入字符 mstr insertString:

43、mutable atInde*:7; NSLog(%,mstr); /插入末尾进展拼接 mstr insertString: and string B atInde*:mstr length; NSLog(%,mstr);/根据*围删除子字符串mstr deleteCharactersInRange: NSMakeRange(16,13);NSLog(%,mstr);字典对象NSMutableDictionary词典dictionary是由键-对象对组成的数据集合。与在词典中查找单词定义一样,可以通过对象的键从Objective-C词典中获取需要的值。词典中的键必须是单值的,可以是字符串,也可

44、以是其他对象类型。和键关联的值可以是任何对象类型。例如,#importint main(int argc,char *argv)NSMutableDictionary *glossary=NSMutableDictionary dictionary;/存储三个条目在类别中glossary setObject:A class defined so other classes can inherit from it forKey:abstract class;glossary setObject:To implement all the methods defined in a protocol

45、forKey:adopt;glossary setObject:Storing an object for later use forKey:abstract class;/检索并显示NSLog(abstract class:%,glossary objectForKey:abstract class);NSLog(adopt:%,glossary objectForKey:adopt);NSLog(archiving:%,glossary objectForKey:archiving);return 0;8.3集合对象NSSet、NSMutableSet、NSInde*Setset是一组单值

46、对象集合,可以是可变的,也可以是不可变的。操作包括:搜索、添加、删除集合中的成员,比拟两个集合、计算两个集合的交集和并集等。主要有三个类NSSet、NSMutableSet、NSInde*Set。常用的集合方法如下表所示,九、内存管理和自动引用计数Objective-C会通过类对象发送alloc消息生成实例对象,alloc的作用就是分配内存。生成的实例对象用完之后如果不被释放的话,就会发生内存泄漏。Objective-C提供了一种动态的内存管理方式,称为引用计数。这种方式会跟踪每个对象被引用的次数,当对象引用的次数为0时,系统就会释放这个对象所占用的内存。这种内存管理方式称为基于引用计数的内存

47、管理。还有一种称为自动引用计数的内存管理(ARC)。自动引用计数使开发者不需要考虑何时使用retain、release、autorelease管理内存,它提供了自动评估对象生存期的功能,在编译期间会自动参加适宜的管理内存的方法。除了ARC之外,Objective-C2.0还引入了另外一种自动内存管理机制垃圾回收。除了垃圾回收时,就不再需要通过引用计数来管理创立的对象,系统会自动识别哪些对象仍在使用,哪些对象可以回收。9.1手动引用计数内存管理Objective-C使用了一种叫作引用计数的技术来管理对象所占用的内存。每个对象都有一个与之相关的整数,称作它的引用计数。当*段代码不在使用这个对象时,

48、则将对象的引用计数器值减1。也就是说,引用计数器就是指程序中到底有多少个地方需要访问这个对象。例如,使用alloc和初始化方法创立一个对象时,该对象的引用计数器的初始值为1。假设有一个类A在进展处理的过程中需要使用到实例B,为了防止实例B被别的对象随意释放,类A会事先给实例B发送一个retain消息。这样,每执行一次retain,实例B的引用计数就会加1。反之,不再需要*个对象时,可以通过发送release消息,使对象的引用计数减1。也就是说,当对象的引用计数值到达0的时候,系统就知道这个对象不再需要了。这时,Objective-C会自动向对象发送一条dealloc消息来释放缓存。在实际编程的

49、时候,我们会遇到很多只用了一次就不再使用的对象。如果这种对象也需要逐个释放,那将会很麻烦。Objective-C提供了一种对象自动释放机制,这种机制的根本思想是把所有需要发送release消息的对象都记录下来,等到需要释放对象时,会给这些对象一起发送release消息。其中,类NSAutoreleasePool自动释放池就起到了记录的作用。Objective-C还提供了一种创立临时对象的方法,这种方法创立的对象都是临时对象,生成之后会被直接参加内部的自动释放池,必须要关心如何销毁。例如,-(id) initWithUTF8String:(const char *) bytes/生成的实例对象的

50、初始化方法,生成的实例对象的初始引数为1。+(id) stringWithUTF8String:(const char *) bytes/生成临时变量的类方法,生成的实例对象会被自动参加到自动释放池中。9.2自动引用计数内存管理ARCAuto Reference Counting是一个编译期技术,利用此技术可以简化Objective-C在内存管理方面的工作量。ARC通过在编译期间添加适宜的retain/release/autorelease等函数,来确保对象被正确地释放。编译器会根据传入的变量是局部变量还是引用变量,返回对象的方法是不是初始化方法initialize等信息来推断应该在何处参加r

51、etain/release/autorelease等函数。这样一来,程序员就可以不再关心是否通过retain或release正确地释放了每个使用的对象,而将更多的精力用于开发程序的核心功能。例如,现在有一个指向*个对象的变量s,假设将一个w对象赋值给s。s=w;赋值操作之后,s原来指向的对象将不能通过s来访问,s需要放弃该对象的所有权。与此同时,s需要获得新赋值对象的w的所有权。编译以上代码的时候,ARC相当于生成了如下代码:w retain;/获得w的所有权id_old=s;/_old用于临时缓存ss=w;/赋值之后,s放弃原来对象的所有权id_old release;/要考虑到对象的释放再

52、次涉及s的情况ARC内存管理往往存在循环引用的问题,例如,类A和类B相互引用,要想把A和B都释放掉,按照规则,只有等到释放B之后才可能释放A,同样,只有在释放A之后才能释放B,当双方都在等待对方释放的时候,就形成了循环引用,结果两个对象都不会被释放,这样就会造成内存泄漏。为了防止循环引用的出现,引入了另外一种类型的变量,这种变量能够引用对象,但不会成为对象所有者,不影响对象本身的回收。称之为弱引用weak reference,弱引用通过存储一个指向对象的指针创立,且不保存对象。Objective-C使用_ _weak修饰符来定义弱引用,如下例所示,_ _weak id temp;_ _weak

53、 NSObject *cacheObj;通常声明的未加_ _weak修饰符的变量都是强引用类型的变量,声明时也可以通过加上_ _strong修饰符来明示变量是强引用类型。9.3垃圾回收垃圾回收garbage collection指的是在程序运行过程中不定时地检查是否有不再使用的对象,如果存在就释放它所占用的内存空间。需要注意的是,垃圾回收是MacOS * 10.5 Leopard之后开场引入的内存管理方法,IOS目前还不支持垃圾回收机制。Mac OS * 10.7和IOS 5以上的系统强烈推荐使用ARC来管理内存,垃圾回收仅仅是作为一种备选方案存在。内存的检查和回收都是由垃圾收集器完成。Mac

54、 OS *中垃圾回收的目标是不再使用的实例对象。C风格的变量、C风格的构造体以及C风格申请的内存都不属于垃圾回收的*围。垃圾回收首先进展的工作就是识别不允许被回收的对象。首先,全局变量和静态变量引用的对象不允许被回收。另外,栈内临时变量引用的对象也不允许被回收。这些称为根集合。如果一个对象的实例变量引用了不允许被回收的对象或根集合中的对象,则这个对象也不允许被回收。垃圾收集器的运行时自适应的,既不以固定的频率运行,也不能通过程序调用运行。当程序运行过程中超过一定量时,垃圾收集器就会被自动触发运行。垃圾收集器通常作为一个单独的线程运行,并对已经不再被使用的对象进展回收。整个回收过程完全是根据占用内存的多少自动完成。. z.

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!