版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、Objective-C程序设计一、 Objective-C简介1.1历史Brad J.Cox在20世纪80年代早期设计了Objective-C语言,它以一种叫做SmallTalk-80的语言为基础。Objective-C在C语言的基础上又加了一层,这意味着对C进行了扩展,从而创造出一门新的程序设计语言,支持对象的创建和操作。1988年,NeXT计算机公司获得了Objective-C语言的授权,并发展了Objective-C的语言库和一个开发环境,即NEXTSTEP。1992年,自由软件基金会的GNU开发环境增加了对Objective-C的支持。所有Free Software Foundatio
2、n(FSF)产品的版权归FSF所有。它以GNU通用公共许可证来发布产品。1994年,NeXT计算机公司和Sun公司联合发布了一个针对NEXTSTEP系统的标准规范,名为OPENSTEP。OPENSTEP在自由软件基金会的实现名称为GNUStep。有一个Linux版本,它包括Linux内核和GNUStep开发环境,这个Linux发行版被十分贴切地命名为LinuxSTEP。1996年12月20日,苹果公司宣布收购NeXT软件公司,NEXTSTEP/OPENSTEP环境将成为苹果操作系统下一个主要发行版本OS X的基础。这个开发环境的版本被苹果公司称为Cocoa。它内置了对Objective-C语言
3、的支持,并结合了Project Builder(后继版本为Xcode)和Interface Builder等开发工具,苹果公司为Mac OS X上的应用程序开发创建了一个功能强大的开发环境。2007年,苹果公司发布了Objective-C语言的升级版,并称之为Objective-C 2.0。1.2第一个Objective-C程序Objective-C是非常实用的语言。它是一个用C写成很小的运行库,令应用程序的尺寸增加很小,和大部分OO系统使用极大的VM执行时间会取代了整个系统的运作相反。Objective-C写成的程序通常不会比其原始码大很多。Objective-C完全兼容标准C语言,而在此基
4、础上增加了面向对象编程语言的特性以及Smalltalk消息机制。开发工具:Xcode 下载地址:实例代码:#import int main(int argc,const char * argv) autoreleasepool NSLog(Hello World!); return 0;Objective-C源文件使用.m作为文件的扩展名。表1.1列出了常见的文件扩展名。表1.1代码解释:(1)注释:/或/* */(2)将文件信息导入或者包含到文件中,其中包含其他类和函数的有关信息。(3)main特殊名称,准确地表示程序在何处执行。(4)“autorele
5、asepool”自动释放池:使得应用在创建对象时,系统能够有效地管理应用所使用的内存。(5)调用名为NSLog的函数,传递给NSLog函数的参数是字符串:“Hello World!”(符号位于一对双引号的字符串前面,成为NSString对象)。NSLog不仅能 显示简单短语,还能显示变量的值及计算结果。例如,NSLog(The sum of %i and %i is %i,value1,value2,sum);可以按格式输出变量的值。二、Objective-C程序设计初步2.1基本数据类型和表达式2.1.1基本数据类型与C+语言基本相同,不同的是,Objective-C添加了一种id类型,id
6、数据类型可存储任何类型的对象,从某种意义上说,它是一般对象类型。id类型是多态和动态绑定的基础。基本数据类型如表2.1所示,表表达式与所有的程序设计语言一样,运算符具有优先级,优先级较高的运算符首先求值。如果优先级相同,可按照“从左到右”或者“从右到左”的方向来求值,具体按哪个方向取值取决于运算符。例如常见的算术运算符、逻辑运算符、赋值运算符等等。2.2基本控制结构与大多数程序设计语言相似,包括顺序、选择、循环结构,在此不再累述。三、类、对象与方法入门3.1基本概念对象对象是人们要进行研究的任何事物,从最简单的整数到复杂的飞机等均可看作对象,它不仅能表示具体的事物,还能表示抽象
7、的规则、计划或事件。对象的状态和行为对象具有状态,一个对象用数据值来描述它的状态。对象还有操作,用于改变对象的状态,对象及其操作就是对象的行为。对象实现了数据和操作的结合,使数据和操作封装于对象的统一体中类具有相同特性(数据元素)和行为(功能)的对象的抽象就是类。因此,对象的抽象是类,类的具体化就是对象,也可以说类的实例是对象,类实际上就是一种数据类型。类具有属性,它是对象的状态的抽象,用数据结构来描述类的属性。类具有操作,它是对象的行为的抽象,用操作名和实现该操作的方法来描述。类的结构在客观世界中有若干类,这些类之间有一定的结构关系。通常有两种主要的结构关系,即一般-具体结构关系,整体-部分
8、结构关系。一般-具体结构称为分类结构,也可以说是“或”关系,或者是“is a”关系。整体-部分结构称为组装结构,它们之间的关系是一种“与”关系,或者是“has a”关系。消息和方法对象之间进行通信的结构叫做消息。在对象的操作中,当一个消息发送给某个对象时,消息包含接收对象去执行某种操作的信息。发送一条消息至少要包括说明接受消息的对象名、发送给该对象的消息名(即对象名、方法名)。一般还要对参数加以说明,参数可以是认识该消息的对象所知道的变量名,或者是所有对象都知道的全局变量名。类中操作的实现过程叫做方法,一个方法有方法名、返回值、参数、方法体。3.2 Objective-C中的面向对象下面采用面
9、向对象的方法编写一个用于处理分数的程序,代码如下所示,#import /-interface部分-interface 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
10、 numerator=n;-(void) setDenominator:(int) d denominator=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 va
11、lue of myFraction is :); myFraction print; return 0;代码解释:interface部分用于描述类和类的方法;implementation部分用于描述数据(类对象的实例变量存储的数据),并实现在接口中声明方法的实际代码;program部分实现了程序的预期目的。(1)interface部分包含两个部分,首先需要告诉Objective-C编译器该类来自何处,也就是说,必须为它的父类命名。其次,必须定义在处理该类的对象时将要用到的各种操作或方法的类型。该部分的一般格式类似于下列语句:interface NewClassName: ParentClass
12、Name propertyAndMethodDeclarations;endObjective-C中变量的名称必须以字母或下划线(_)开头,之后可以是任何字母、下划线或者09之间的数字组合。对于大小写敏感。确定名称时,应该能反映变量或对象使用意图的名称。Objective-C中的方法分为类方法和实例方法,其中,负号(-)表示是实例方法,正号(+)表示是类方法。方法的完整定义如图2.1所示,图2.1方法定义(2)implementation部分implementation部分包含声明在interface部分的方法的实际代码,且需要指定存储在类对象中的数据类型。在interface部分声明方法,并
13、在implementation部分定义它们。implementation部分的一般格式如下:implementation NewClassName memberDeclarations;methodDefinitions;end其中,memberDeclarations部分指定了哪种类型的数据将要存储到Fraction中,以及这些数据类型的名称。在这一部分声明的变量成为实例变量。methodDefinitions部分包含在interface部分指定的每个方法的代码中。每种方法的定义通过方法的类型、返回值和参数进行标识。2.3 program部分program部分包含解决特定问题的代码,必须有一
14、个名为main()的函数作为程序开始的地方。如前段代码所述,通过以下程序行定义了一个名为myFraction的变量:Fraction *myFraction;这一行表示myFraction是一个Fraction类型的对象(*号表明myFraction是Fraction对象的引用,存储了一个内存地址,表明对象数据在内存中的位置)。使用myFraction=Fraction alloc init向某个类发送alloc消息获得该类的新实例,alloc保证所有的实例变量都变成初始状态。使用init方法初始化类的实例变量,init方法返回一个值,即被初始化的对象。下一步,程序行myFraction se
15、tNumerator:1 将控制转到Fraction类中定义的setNumerator方法,将myFraction的分子设置为1。四、Objective-C中的类4.1分离接口和实现文件通常,将类的声明(即interface部分)放在它自己的名为class.h文件中。而类的定义(即implementation部分)通常放在相同名称的文件中,但扩展名为.m。将接口和实现的部分分别放入两个文件,编译器会单独编译每个文件。要使用该类,只需导入接口文件即可。当编译器处理包含实现部分的文件时,需要接口部分的信息,因此需要导入.h文件。要把包含main函数的文件名保存为main.m,作为程序的入口。4.2
16、合成存取方法从Objective-C 2.0开始,可自动生成设值方法和取值方法(统称为存取方法)。首先,在接口部分使用property指令标识属性。这些属性的命名与实例变量相同。然后,在实现部分使用synthesize指令。例如,接口部分有如下代码,interface Fraction : NSObjectproperty int numerator,denominator;-(void) print;-(double) convertToNum;end#import Fraction.h在实现部分,没有包含下列设值和取值方法的定义:numerator、denominator、setNumbe
17、r:和setDenominator。使用synthesize指令让编译器自动生成或合成这些方法。implementation Fractionsynthesize 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语言允许使用点运算符获取所需值。例如,myFra
18、ction.numerator等价于myFraction numerator,还可以使用点运算符进行赋值,例如myFraction.numerator=1等价于myFraction setNumerator: 1。4.4具有多个参数的方法通过列出每个连续的参数并用冒号将其连接起来,就可以定义一个接收多个参数的方法。用冒号连接的参数将成为这个方法名的一部分。例如,在接口文件中添加setTo:over:声明,#import/定义Fraction类interface Fraction :NSObjectproperty int numerator,denominator;-(void) print;
19、-(void) setTo:(int) n over:(int) d;end然后,在实现中添加新方法的定义。#import Fraction.himplementation Fractionsynthesize numerator, denominator;-(void) print NSLog(%i/%i,numerator,denominator);-(void) setTo:(int) n over: (int) d numerator=n; denominator=d;end7.5局部变量、方法参数、静态变量局部变量、方法参数、静态变量与C语言类似,不再累述。需要强调的是,局部变量使用
20、前必须初始化,静态变量会自动初始化。7.6 self关键字关键字self用来指明对象是当前方法的接收者。例如, 有如下代码,-(void) add: (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
21、.1根类没有父类的类位于类层次结构的最顶层,称为根(root)类。自定义的类都属于NSObejct根类的派生类。5.2通过继承来扩展与C+、java等面向对象语言相似,Objective-C中定义的父类的非私有实例变量和方法都会称为新类定义的一部分。例如,interface ClassA:NSObject int x;-(void) initVar;endimplementation ClassA-(void) initVar x=100;end定义一个名为ClassB的新类,继承自ClassAinterface ClassB:ClassA-(void) printVar;endimpleme
22、ntation ClassB-(void) printVar NSLog(x=%i,x);end5.3方法覆写与其他面向对象语言类似,在子类中使用和父类相同的名称定义的方法代替或覆写父类中的方法,新方法必须具有相同的返回类型,并且参数的数目要与覆写的方法相同。如果在不同的类中有名称相同的方法,则根据作为消息的接收者的类选择正确的方法。六、多态、动态类型、动态绑定6.1多态多态按字面的意思就是“多种状态”。在面向对象语言中,接口的多种不同的实现方式即为多态。多态性是允许你将父对象设置成为一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的
23、说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。C+中,实现多态有以下方法:虚函数,抽象类,覆盖,模板。6.2动态绑定和id类型id可以用来存储属于任何类的对象,会导致程序无法区分某个实例对象到底是哪个类的对象。Objective-C总是先判定对象所属的类,然后在运行时确定需要动态调用的方法,而不是在编译时。换句话说,动态绑定指的就是在程序运行时才能确定对象的属性和需要响应的消息。例如,#import Fraction.h#import Complex.hint main(int argc, char *argv) autoreleasepool id dataValue; Frac
24、tion *f1=Fraction alloc init; Complex *c1=Complex alloc init; f1 setTo: 2 over 5; c1 setReal: 10.0 andImaginary: 2.5; /dataValue获得了一个分数 dataValue=f1; dataValue print; /dataValue获得了一个Complex数 dataValue=c1; dataValue print;return 0;当系统将print消息发送给dataValue时,它首先会检查dataValue中存储的对象所属的类。结合多态、动态绑定,可以轻易地编写出可
25、以向不同类的对象发送相同消息的代码。例如,考虑可用来在屏幕上绘制对象的draw方法。你可能为每个图像对象(比如文本、圆、矩形、窗口,等等)定义了不同的draw方法。如果要绘制的特定对象存储在一个名为currentObject的id变量中,仅仅通过发送draw消息就可以在屏幕上进行绘制,语句如下,currentObject draw。6.3编译时和运行时检查因为存储在id变量中的对象类型在编译时无法确定,所以一些测试会推迟到运行时进行。例如,Fraction *f1=Fraction alloc init;f1 setReal: 10.0 andImaginary: 2.5;当编译此段代码时,将
26、显示以下消息:Fraction may not respond to setReal:andImaginary: 现在考虑下面的代码序列:id dataValue=Fraction alloc init;dataValue setReal:10.0 andImaginary:2.5;这段代码在编译时,编译器并不知道存储在dataValue中的对象类型,直到运行时,会出现如下出错信息:-Fraction setReal:andImaginary:unrecognized selector sent to instance 0x103f00将一个变量定义为特定类的对象时,应尽量使用静态类型。“静态
27、”指的是对存储在变量中对象的类型进行显式声明。这时候,编译器能够通过检查确定应用于对象的方法是由该类定义的还是由该类继承的,否则将显示警告信息。编译时进行的类型检查的要点如下,(1) 对于id类型的变量,调用任何方法都能够通过编译。(2) Id类型的变量和被定义为特定类的变量之间可以相互赋值。(3) 被定义为特定类对象的变量(静态类型)如果调用了类或方法中未定义的方法,编译器就会提示警告。(4) 若是静态类型的变量,子类类型的实例变量可以赋值给父类类型的实例变量。(5) 若要判断到底是哪个类的方法执行了,不要看变量所声明的类型,而要看实际执行时这个变量的类型。(6) Id类型并不是(NSObj
28、ect*)类型。6.4 使用try处理异常在Objective-C中,处理异常情况的语法格式为,try statement statement .catch (NSException *exception) statement statement .七、分类和协议7.1分类与扩展有时候在面对一个类定义时,可能想要添加一些新方法。例如,对于Fraction类,除了将两个分数相加的add:方法之外,还想要将两个分数相减、相乘、相除的方法。分类提供了一种简单的方式,用它可以将类的定义模块化到相关方法的组或分类中。它还提供了扩展现有类定义的简便方式,并且不必访问类的源代码,也无须创建子类。例如,#im
29、port /定义Fraction类interface Fraction : NSObjectproperty int numerator,denominator;-(void) setTo:(int) n over:(int) d;-(Fraction *) add:(Fraction *)f;-(void) reduce;-(double) convertToNum;-(void) print;end从接口部分删除add:方法,并将其添加到新分类,同时添加其他三种要实现的数学运算。新的MathOps分类的接口部分代码如下:#import Fraction.hinterface Fractio
30、n (MathOps)-(Fraction *) add:(Fraction *) f;-(Fraction *) mul:(Fraction *) f;-(Fraction *) sub:(Fraction *) f;-(Fraction *) div:(Fraction *) f;end其中,Fraction(MathOps)表示正在为Fraction类定义新的分类,并且它的名称为MathOps。注意,分类不能添加新的实例变量。创建一个未命名的分类,且在括号“()”之间不指定名字,这种特殊的语法格式定义称为类的扩展。与分类不同的是,扩展可以添加新的实例变量。注意,未命名分类中的方法都是私有
31、的,如果需要写一个类,而且数据和方法仅供这个类本省使用,未命名分类比较合适。例如,#import GraphicObject.h/类的扩展interface GraphicObject()property int uniqueID;-(void) doStuffWithUniqueID:(int) theID;endimplementation GraphicObjectsynthesize uniqueID;-(void) doStuffWithUniqueID:(int) myID self.uniqueID=myID;通过添加一个新的实例变量uniqueID扩展了GraphicObjec
32、t类,并合成了设值与取值方法。另外,还添加了一个名为doStuffWithUniqueID:的方法。7.2协议与代理协议是多个类共享的一个方法列表。协议表示对象的作用和行为的方法的集合体。在对象模型化的软件世界里,不同的对象也可能包含相同的方法集合,但通常情况下,这些对象之间并不是继承关系。例如,数组、线性表、二分查找树就是这样的集合对象。这些类之间并没有继承关系,但都有添加、删除、升序排序这样的操作。这些操作就是协议。协议中列出的方法没有相应的实现,协议提供了一种方式,可以用指定的名称定义一组方法。这些方法有些是选择实现,有些是必须实现。可以使用命令符required(默认),optiona
33、l用来设定其后出现的方法是可选的还是必选的。定义一个协议很简单,只需使用protocol指令。例如,在头文件NSObject中定义NSCopying协议的方式:protocol NSCopying-(id) copyWithZone: (NSZone *)zone;end如果你的类采用NSCopying协议,则必须实现名为copyWithZone:的方法。通过在interface行的一对尖括号()内列出协议名称,可以告知编译器你正在采用一个协议。例如interface AddressBook:NSObject这说明,AddressBook是父类为NSObject的对象。并且它遵守NSCopyi
34、ng协议,必须要在实现部分定义它们。可以使用conformsToProtocol:方法检查一个对象是否遵循某项协议。例如,如果有一个名为currentObject的对象,并且想要查看它是否遵循Drawing协议,代码如下,id currentObejct;if(currentObject conformsToProtocol: protocol (Drawing)=YES)/执行协议中的方法定义了协议的类可以看做是将协议定义的方法代理给了实现它们的类。这样,类的定义可以更为通用,因为具体的动作有代理类来承担,响应某些事件或者定义某些参数。例如,当你在iPhone上建立一个表格时,会使用到UIT
35、ableView类。但是这个类不清楚表格的标题是什么,需要包含多少个区块或是包含多少行,填充表格的内容是什么。所以代理为你定义了一个UITableViewDataSource协议。如果它需要消息,比如表格中的每个区块有多少行,它就会调用类中实现协议的相关方法。UITableView类还定义了其他的协议,如UITableViewDelegate。协议中还定义了一些方法,如表格中某些行被选中需要怎么样。八、Foundation框架8.1 Foundation简介框架是由许多类、方法、函数和文档按照一定的逻辑组织起来的集合,以便使程序开发变得更容易。在Mac OS X系统下大约有90多个框架,这些框
36、架可以用来开发应用程序,处理Mac的Address Book结构、播放DVD、使用QuickTime播放电影等。为所有的应用程序开发奠定基础的框架称为Foundation框架,它允许使用一些基本对象,如数字和字符串,以及一些对象集合,如数组、字典和集合。还包括处理日期和时间、自动化的内存管理、处理基础文件系统、存储对象、处理几何数据结构。Application Kit框架包含广泛的类和方法,它们用来开发交互式图形应用程序,使得开发文本、菜单、工具栏、表、文档和窗口之类的过程变得十分方便。在Mac OS X系统中,术语Cocoa指的是Foundation框架、Application Kit框架和
37、名为Core Data的第三方框架。术语Cocoa Touch指的是Foundation、Core Date、UIKit框架。8.2数字对象、字符串、集合8.2.1数字对象(NSNumber)int型、float型和long型都是Objective-C语言中的基本数据类型。不能够向它们发送消息。如果需要存储基本数据类型,可以使用NSNumber类,它会根据这些数据的类型创建对象。例如,#import int main(int argc,char *argv) autoreleasepoolNSNumber *myNumber,*floatNumber,*intNumber;NSInteger
38、myInt; /integer型值intNumber=NSNumber numberWithInteger:100;myInt=intNumber integerValue;NSLog(%li,myInt);/long型值myNumber=NSNumber numberWithLong:0xabcdef;NSLog(%lx,myNumber longValue);/char型值myNumber=NSNumber numberWithChar:X;NSLog(%c,myNumber charValue);/float型值myNumber=NSNumber numberWithFloat:100.
39、00;NSLog(%g,myNumber floatValue);/验证两个Number是否相等if(intNumber isEqualToNumber:floatNumber=YES)NSLog(Numbers are equal);elseNSLog(Numbers are not equal);/验证一个number是否小于或大于另一个numgerif(intNumber compare:myNumber=NSOrderedAscending)NSLog(First number is less than second); return 0;对于每种基本数据类型,类方法都能为它创建一个N
40、SNumber对象,并设置为指定的值。这些方法以numberWith开头,紧接数据的类型,如numberWithLong、numberWithFloat等,下表列出了NSNumber对象设值的类和实例方法,以及获取这些值相应的实例方法。表8.1 NSNumber的创建和检索方法8.2.2字符串对象(NSString)Foundation框架支持一个名为NSString的类,用于处理字符串对象,使用这个类的方法更容易开发出具有本地化的应用程序,能够在世界上不同的语言环境下使用。要使用Objective-C语言创建一个常量字符串对象,需要在字符串开头设置一个字符,例如,#importint mai
41、n(int argc,char *argv) autoreleasepoolNSString *str=Programming is fun;NSLog(%,str); return 0;可以使用格式化字符%显示数组、字典和集合全部内容。事实上,通过覆盖继承的description方法,这可使用这些格式字符显示自己的类对象。如果不覆盖方法,NSLog仅仅显示类名和该对象在内存中的地址,这是从NSObject类继承的description方法的默认实现。NSString类中提供了一些方法,如获取字符串长度str1 length、将一个字符串复制到另一个字符串NSString stringWith
42、String: str1、验证两个字符串是否相等str1 isEqualToString :res等等。NSString中的常用方法如下表所示,表8.2 NSString中的处理方法NSString类处理的是不可变字符串,经常需要处理字符串并更改字符串中的字符,这种类型的字符串使用NSMutableString类处理。例如,#import int main(int argc,char *argv) autoreleasepool NSString *str1=This is string A; NSString *search,*replace; NSMutableString *mstr;
43、NSRange substr; /从不可变字符串创建可变字符串 mstr=NSMutableString stringWithString: str1; NSLog(%,mstr); /插入字符 mstr insertString:mutable atIndex:7; NSLog(%,mstr); /插入末尾进行拼接 mstr insertString: and string B atIndex:mstr length; NSLog(%,mstr);/根据范围删除子字符串mstr deleteCharactersInRange: NSMakeRange(16,13);NSLog(%,mstr)
44、;8.2.3字典对象(NSMutableDictionary)词典(dictionary)是由键-对象对组成的数据集合。与在词典中查找单词定义一样,可以通过对象的键从Objective-C词典中获取需要的值。词典中的键必须是单值的,可以是字符串,也可以是其他对象类型。和键关联的值可以是任何对象类型。例如,#importint main(int argc,char *argv)NSMutableDictionary *glossary=NSMutableDictionary dictionary;/存储三个条目在类别中glossary setObject:A class defined so o
45、ther classes can inherit from it forKey:abstract class;glossary setObject:To implement all the methods defined in a protocol forKey:adopt;glossary setObject:Storing an object for later use forKey:abstract class;/检索并显示NSLog(abstract class:%,glossary objectForKey:abstract class);NSLog(adopt:%,glossary
46、 objectForKey:adopt);NSLog(archiving:%,glossary objectForKey:archiving);return 0;8.3集合对象(NSSet、NSMutableSet、NSIndexSet)set是一组单值对象集合,可以是可变的,也可以是不可变的。操作包括:搜索、添加、删除集合中的成员,比较两个集合、计算两个集合的交集和并集等。主要有三个类NSSet、NSMutableSet、NSIndexSet。常用的集合方法如下表所示,九、内存管理和自动引用计数Objective-C会通过类对象发送alloc消息生成实例对象,alloc的作用就是分配内存。生
47、成的实例对象用完之后如果不被释放的话,就会发生内存泄漏。Objective-C提供了一种动态的内存管理方式,称为引用计数。这种方式会跟踪每个对象被引用的次数,当对象引用的次数为0时,系统就会释放这个对象所占用的内存。这种内存管理方式称为基于引用计数的内存管理。还有一种称为自动引用计数的内存管理(ARC)。自动引用计数使开发者不需要考虑何时使用retain、release、autorelease管理内存,它提供了自动评估对象生存期的功能,在编译期间会自动加入合适的管理内存的方法。除了ARC之外,Objective-C2.0还引入了另外一种自动内存管理机制垃圾回收。除了垃圾回收时,就不再需要通过引
48、用计数来管理创建的对象,系统会自动识别哪些对象仍在使用,哪些对象可以回收。9.1手动引用计数内存管理Objective-C使用了一种叫作引用计数的技术来管理对象所占用的内存。每个对象都有一个与之相关的整数,称作它的引用计数。当某段代码不在使用这个对象时,则将对象的引用计数器值减1。也就是说,引用计数器就是指程序中到底有多少个地方需要访问这个对象。例如,使用alloc和初始化方法创建一个对象时,该对象的引用计数器的初始值为1。假设有一个类A在进行处理的过程中需要使用到实例B,为了防止实例B被别的对象随意释放,类A会事先给实例B发送一个retain消息。这样,每执行一次retain,实例B的引用计
49、数就会加1。反之,不再需要某个对象时,可以通过发送release消息,使对象的引用计数减1。也就是说,当对象的引用计数值达到0的时候,系统就知道这个对象不再需要了。这时,Objective-C会自动向对象发送一条dealloc消息来释放缓存。在实际编程的时候,我们会遇到很多只用了一次就不再使用的对象。如果这种对象也需要逐个释放,那将会很麻烦。Objective-C提供了一种对象自动释放机制,这种机制的基本思想是把所有需要发送release消息的对象都记录下来,等到需要释放对象时,会给这些对象一起发送release消息。其中,类NSAutoreleasePool(自动释放池)就起到了记录的作用。Objective-C还提供
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 企业酒水采购制度
- 教学系采购制度模板
- 国企公司采购制度
- 企业采购合同制度
- 行政员工福利采购制度
- 公务采购管理制度
- 原材料采购登记制度范本
- 采购材料管理制度
- 自来水公司材料采购制度
- KTV消防宣传教育培训制度
- 2025年大学《数据警务技术-警务大数据基础》考试参考题库及答案解析
- 2026年安徽职业技术学院单招职业适应性测试题库及答案1套
- 华为交换机维护操作手册
- GB/T 11918.4-2025工业用插头、固定式或移动式插座和器具输入插座第4部分:有或无联锁带开关的插座
- 中国抗癌协会脑胶质瘤整合诊疗指南2025版
- 智慧港口等级评价指南集装箱码头(T-CPHA9-2022)
- 化工培训课件
- 2024青岛港湾职业技术学院教师招聘考试真题及答案
- 洋地黄类药物护理要点
- 产业升级中人工智能促进城乡收入差距缩小分析报告
- DB46∕T 626-2024 黎家宴服务规范
评论
0/150
提交评论