




已阅读5页,还剩83页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
一、面向对象编程介绍面向对象编程基本概念 (1/4)1、面向对象概念目前你可能听说过很多面向对象的语言,如C+和Java,本课程的Objective-C同样也是一种面向对象的编程语言。面向对象有一个共同的特征就是允许你使用有别于面向过程语言的方式来设计并编写程序。面向过程语言使程序员通过编写由数据类型组成的程序块或函数来操作数据,这就造成程序设计人员采用功能块的方式来设计程序,采用这种方式无法使程序应该实现什么和怎么来实现彻底分开。而面向对象语言能够让程序设计人员采用一种接近真实世界的方式来设计程序,而不仅仅是考虑需要处理的数据和功能实现。面向对象提出了对象的概念,而且你可以将消息发送给这些对象。我们这里所说的对象就是当其他程序或对象调用这个对象时,它可以操作自身的数据,而对象本身具有相应的行为和属性。例如我们有这么一个对象,它可以在窗体上画一个长方形,此时你只需要给它发送一个消息,这个消息包含长和宽以及位置坐标,那么这个对象收到消息后就可以在窗体上画出一个长方形了。右侧是一个非常简单的Objective-C程序,如果你已经学完了C语言基础的课程,那么这个程序对你来说肯定太简单了,它要做的就是在终端上打印出Hello, Objective-C!的字样,同时给操作系统返回数字0。hello.m#import int main(int argc, const char *argv) NSLog(Hello, Objective-C!); return (0); / main面向对象编程基本概念 (2/4)2、什么是Objective-C?Objective-C语言是一种非常强大的面向对象编程语言,它对ANSI-C语言进行了扩展,增加了很多新的关键字和编译器的指令,并增加了向对象发送消息的句法。这种对C语言非常简单的扩展,完全由Objective-C的新编译器libobjc来完成,当然程序员通常情况下,不用关心这个新的编译器。在编译Objective-C源代码的过程中,新增的面向对象功能由称为Runtime库来完成。这个Runtime库使动态的决定类型和绑定成为可能,使Objective-C语言成为了真正的面向对象编程语言。由于Objective-C语言扩展了C语言的构造(增加了很多编译器的指令和句法),你依然可以很轻松地将你的C语言代码集成进Objective-C中。实际上,一个Objective-C的程序让C语言程序员看起来很亲切,因为Objective-C语言依然使用main函数。相对于其他编程语言,Objective-C比C+和Java更加的动态话,因为所有的方法调用都被放在了运行时。温馨提示:按F11键可全屏编辑代码 candoc.m#import #include int main(int argc, const char *argv) /* 在这里键入Objective C 和 C 代码 */ NSLog(Objective-C Standard stringn) printf(you can program C in OCn); return(0);面向对象编程基本概念 (3/4)3、Objective-C的历史作为编程语言来说,Objective-C有悠久的历史。20世纪80年代早期Objective-C被Stepstone公司发明,作者是Brad Cox和Tom Love。80年代后期,NeXT计算机有限责任公司获得了使用Objective-C来开发NeXTStep框架的授权,也就是后来的Cocoa。Objective-C是非常“实际”的语言。它使用一个用C写成的、很小的运行库,使用其开发的应用程序占用空间会很小。和大部分面向对象的系统使用极大的虚拟机的执行时间取代整个系统的运作相反,用Objective-C写成的程序通常不会比其原始码大很多。Objective-C的最初版本并不支持垃圾回收,虽然某些第三方版本已加入这个功能, 苹果公司在其Mac OS X 10.3中仍未引入这个功能。另一个问题是Objective-C不包括命名空间机制(namespace mechanism),取而代之的是程序设计师必须在其类别名称加上前缀,时常引致冲突。在2004年,在Cocoa编程环境中,所有Mac OS X类别和函数式均有“NS”作为前缀,例如,NSButton或CGImageRef就能清楚知道NSButton属于UIKit框架而CGImageRef属于Core Graphics框架。使用“NS”是由于这些类别的名称在NeXTSTEP开发时定下。和C+不同,Objective-C不支持运算符重载。但和Java相同,Objective-C只容许对象继承一个类别(不设多重继承)。面向对象编程基本概念 (4/4)4、建立第一个真正的Objective-C程序下面的例子中,我们将告诉你如何建立一个真正的具有面向对象概念的Objective-C程序。这个程序虽然只是简单的显示一个字符串这是类Test中的字符串,虽然之前我们也可以向屏幕输出一个字符串,但这次,我们为了证明Objective-C语言的面向对象属性,换了一种方法,具体请看:source.m#include /引入C语言标准函数库(为了使用printf函数#include /引入Objective-C标准函数库/*声明一个类Test并定义类中的方法classStringValue。*/interface Test+ (const char *) classStringValue;end/*实现一个类及方法classStringValue。 */implementation Test+ (const char *) classStringValue;return 这是类Test中的字符串;endint main(int argc, const char *argv) printf(%sn, Test classStringValue); /使用C语言中的printf return 0; 二、详解 Objective-C语言 Objective-C新增功能(非面向对象) (1/1)1、Objective-C新增功能(非面向对象方面)Objective-C语言增加了一些C语言中没有提供的功能,包括:增加了BOOL数据类型,该类型可以存储YES或者NO的布尔值的数据类型BOOL的值是NO时的值为0,YES的值为1使用双斜杠(/”)来作为注释增加了#import标示符,它可以指导编译器仅将目前没有被引用过的文件引用进来,这个标示符仅能引用Objective-C的头文件而不能引用传统C语言的头文件。 bool.m #import /#import关键字,引入Objective-C头文件 int main(int argc, const char *argv) BOOL isNumA=NO;/BOOL类型变量声明并初始化 NSLog(%d,isNumA); /输出BOOL变量的值 isNumA=YES; /改变BOOL变量的值 NSLog(%d,isNumA); return (0); Objects(对象) (1/4)1、什么是面向对象编程什么是面向对象编程,面向对象编程是基于这样一种概念:软件系统是由彼此互相交互的对象组成的,这很类似于我们现实中的物理世界。 面向对象的编程模型使程序员更容易的理解程序是如何工作的,因为面向对象编程使程序看起来更加的直观。而对象的使用还可以使程序的设计更加简单,可以将一个大的问题分解成为很小的部分,分解成独立的对象,各个对象间彼此相互关联。 对象更像是一段可以实现某些功能的很小的程序段,他们可以被其他程序或者对象调用。一个对象可以接收来自外界的消息,并且根据消息来改变自身的状态,例如:在一个画图程序中,一个长方形的对象的长度和位置。 在软件中,一个对象被实例化成变量,对象变量包含自身的属性和方法(类似于C语言中的函数),通过接收消息,调用方法来改变自身状态来向给对象发送消息的程序或者对象返回消息。 当程序员建立一个应用程序时,与面向过程编程中调用函数来实现程序的功能不同,在面向对象中,所有需要做的就是发送消息给恰当的对象。 给一个对象发送消息的表达式,是Objective-C中比C语言中增加的新功能,具体如下: objectName message; 注意,方括号需要包括对象的名字和要传入的消息。 代替调用对象方法的说法,更确切的说法是,告诉一个对象根据给它的消息去执行它自己的方法。而关于消息message的具体格式,我们会在后面的课程中详细讨论。Objects(对象) (2/4)2、Id和nilObjective-C语言中定义了一种新的标识对象的类型:idid类型指向了一个对象的实例,下面的代码声明了一个对象类型的变量buttonid button;当button类型的对象最终被创建出来后,变量名button指向了实例变量的数据,但是,在button变量指向具体的值之前,它实际上不指向任何代码。那么button应该指向什么呢?为了解决这个问题,Objective-C语言定义了一个新的关键字:nil,当定义了一个id类型的变量并没有给它赋予任何具体值得时候,就将nil赋值给button,如下:id button = nil;在变量声明的时候就初始化成nil。在你给一个对象发送消息之前,你可以测试一下这个对象是否存在。如果测试失败,证明这个对象不存在,然后你就可以执行一些相关的代码去处理对象不存在时的状况。例如:if (anObject != nil) . /* send message */else . /* do something else */头文件objc/objc.h中定义了id,nil以及其他Objective-C语言中基本的数据类型。你需要在你的程序中使用#include 将上述头文件导入程序。Objects(对象) (3/4)3、消息(Message)消息是Objective-C语言中向对象传递指令的机制,你可以让一个对象去为你做一些事情,让它改变它自己内部的状态或者向它询问一些你想知道的信息。 消息通常会调用一个方法,结果是接收消息的对象用某种方式回应这个消息,发送给对象的消息操作了对象和数据。对于返回值,类似于C语言,不过,Objective-C语言要求返回值必须是个对象。 对象之相应正确格式的消息,给对象发一个消息,你需要将对象名和消息名称或者是方法名以及方法所附带的参数,全部放进方括号中。给一个对象发消息的表达式如下:receiver messagename;其中receiver是一个对象。 运行时环境会根据消息名调用对象的方法,例如,调用mySquare对象display方法的消息如下:mySquare display; 向对象传递消息时也可以附带参数,附带参数时要使用冒号,冒号也是messagename的一部分,所以要调用setFrameOrigin: 方法的语句如下:button setFrameOrigin: 10.0 : 10.0;一个Labels的描述参数是:button setWidth: 20.0 height: 122.0;上面的消息会调用setWidth:height: 这个方法传递一个可变参数数量的消息给对象的语句如下:receiver makeList: list, argOne, argTwo, argThree;如果给nil发送消息,结果会使应用程序崩溃吗,在Objective-C语言中,是不会崩溃的。如下:nil display;将不会发生任何事!如果发送消息给一个对象并要求一个返回值,可这个对象正处于nil状态,它将返回nil空对象。但是如果这个方法将返回一个比如int这样的基础数据类型,但如果在给该对象发消息时,对象是nil状态,则是不可以的,也就是说,程序员要避免出现这种问题。Objects(对象) (4/4)4、多态性(Polymorphism) 多态性是指针对同一个消息,不同的对象有不同的回应。例如,当不同的客户端对象从服务器对象接受一个相同的消息,他们两个对象的的响应可以是完全不同的。使用动态绑定技术,运行时系统将根据不同的对象类型决定最终执行哪一段代码。Classes(类) (1/4)1、什么是类(classes) 在Objective-C中,一个类,是一个对象的类型。类似于C语言中的结构体(structure),比C语言结构体中只包含变量不同,一个类中,还同时包含有方法,可以理解为C语言中的函数。 当你建立了一个类的实例时,这个实例通常称为对象,会为这个对象分配相应的内存空间,还会分配一个指向这个实例中方法的指针,这个指针会告诉Objective-C的运行时系统(runtime),到哪里去找到该对象的方法等等。无论何时,当向一个对象发送消息时,运行时(runtime)会通过给对象设置的变量名找到对象并运行它的方法。Classes(类) (2/4)2、类的继承(Inheritance) 大部分程序员都会花费大量的时间去定义类,继承(Inheritance)提供了一种非常方便的方法,极大地减少了定义大量类时花费的编码时间。例如:NSButton类可以创建出按钮的对象,因为NSButton中包含了创建一个按钮对象所需的属性和方法。如果一个类可以继承NSButton类中的属性和方法,就像儿子继承父亲的特征一样,那么这个类就是NSButton的子类,而NSButton就是该类的父类。那么这个子类也可以创建出一个按钮对象,但或许增加了一些新的功能,比如可以创建一个拥有彩色边框的按钮。同样地,NSTextField的子类或许可以画出不同的边框。如此,继承的使用就真正地极大地减少了定义类时需要的代码。 在Objective-C语言中,所有的类都继承于NSObject这个类,所以说NSObject这个类是根类(就像树根一样,所有的枝干都发于树根)。所有的类都可以有子类,除了NSObject根类外,其余类都有自己的父类。当类创建出一个新的对象实例变量,这个对象就拥有了它自己的属性和方法,它的父类的属性和方法以及父类的父类的根类NSObject的属性和方法。 当一个新的对象被创建后,系统会分配一定的内存空间给它,并且会初始化这个对象中的各种属性的值。每一个对象中都有一个成员变量isa,这是NSObject类中的成员变量,其指向一个结构体,这个结构体用于表示类的结构体,称之为类结构体。结构体中包括:该类独有的数据成员的类型(注意是类型,不是数据成员的值,地址什么的),函数列表,以及一个指向父类的类结构体指针(因为OC不允许多重继承,所以一个就够了)。其中函数列表通过一个映射列表实现的,给出一个键值将得到一个函数地址如果该键值存在的话。 而且OC里面的类函数调用,或者称之为消息传递(更为贴切一点),都将被编译器改写为一个叫objc_sendMsg(实体对象指针,函数索引值,参数列表)的函数。该函数将通过isa指针,找到类结构体中对应的函数,如果存在则调用该函数,并传递相应参数。否则,通过类结构体的父指针找到父类的类结构体,查找函数是否存在,存在则调用,否则一直向上追溯,如果最终没有找到,则抛出异常。 除了NSObject类之外,每一个类都有一个且仅有一个自己的父类(superclass),但可以有很多的子类,就像自己有很多的孩子。每个类都继承自父类并有自己的特点,所以可以说是父类的一个更精细化的类。 对象可以调用自己的方法,以及父类的方法,父类的父类的NSObject的方法。也可以重新定义祖先的方法(方法名称与祖先相同),这叫重写(overriding),重写的方法也可以被子类继承。Classes(类) (4/4)4、类簇(Class Clusters) 类簇,是由一个抽象的父类及一组私有化(private)的具体子类组成。程序员只能用父类对外提供的接口(interface)来生成类簇中某个具体的子类对象。如下图所示: 上图中,抽象类Number是类簇中各子类的父类,而用灰色表示的各个子类,是私有子类(private subclass),私有子类的意思是,程序员无法访问到这些子类,也无法直接用子类生成对象,程序员只能通过Number这个抽象父类对外公开的接口来生成各个具体子类的对象。为什么需要这样来设计呢?类簇解决的是什么问题呢?让我们还是用上面的例子来说明。 在上图中,Char,UnsignedChar,Short,UnsignedShort,Int,UnsignedInt,LongInt这些子类,都可以存储数字,只不过是不同种类的数字,这些不同种类的数字实际上有很多共同的特点(比如可以从一种类型转换成另外一种,活着它们都可以转换成字符串(string)),那这些不同种类的数字,可以定义成一个类吗?这是不可以的,因为不同种类的数字,它们所占的内存空间并非一样大,如果将它们归并为一个类,效率是非常低的。基于这点现实的考虑,所以提出了类簇(Class Clusters)的设计模式来解决这个经常会出现的问题。其中抽象父类中来定义方法(可以实现比如不同子类间类型转换等等功能),而不定义属性。 引入类簇(Class Clusters)设计模式后,所有的子类均继承自一个抽象的父类(abstract superclass),而具体的子类又是私有的(private subclass),程序员只能通过其共同的抽象父类来生成子类对象,比如上图中的抽象父类是Number那么问题出现了,既然只能通过Number公开的接口来生成子类的对象,那么这个Number是怎么生成我们想要的具体子类对象呢? 为了解决这个问题,类簇中的抽象父类必须定义出生成类簇中不同子类对象的方法(method),程序员通过给抽象父类发送不同的消息,抽象父类返回消息所对应的子类的对象,这就是抽象父类的使命。拿NSNumber类举个例子,NSNumber是一个类簇的抽象父类,下面有Char,Int,Float,Double等这些子类,你可以通过给NSNumber发送如下消息来生成不同子类的对象。NSNumber *aChar = NSNumber numberWithChar:a;NSNumber *anInt = NSNumber numberWithInt:1;NSNumber *aFloat = NSNumber numberWithFloat:1.0;NSNumber *aDouble = NSNumber numberWithDouble:1.0; 上面每一个返回来的对象,aChar/anInt/aFloat/aDouble是类簇中不同子类的对象。让我们动手来试一试,通过类簇中的抽象类NSNumber来生成子类的对象并赋初值,然后再把它们打印出来吧! classclusters.m int main(int argc, const char *argv) NSAutoreleasePool* pool = NSAutoreleasePool alloc init; /无需理会,后面的课程会有详细介绍 NSNumber *aChar = NSNumber numberWithChar:a; /声明一个NSNumber的对象aChar,并给它赋予初值a NSNumber *anInt = NSNumber numberWithInt:1; /声明一个NSNumber的对象anInt,并给它赋予初值1 NSNumber *aFloat = NSNumber numberWithFloat:1; /声明一个NSNumber的对象aFloat,并给它赋予初值1 NSNumber *aDouble = NSNumber numberWithDouble:3.14159; /声明一个NSNumber的对象aDouble,并给它赋予初值3.14159 NSLog(n%cn%in%fn%lg,aChar charValue,anInt integerValue,aFloat floatValue,aDouble doubleValue); /向屏幕打印各个对象的值 pool release; /无需理会,后面的课程会有详细介绍 return (0); NSObject类(The Root Class) (1/2)1、根类 NSObjectNSObject是Objective-C语言的根类(Root class),这个类提供了一些基本且必须的功能,来实现不同子类之间的交互。NSObject被所有子类继承的最基本的功能是以下两个: 分配内存给对象(allocate instances) 将对象连接到他们的类NSObject还提供了一些额外的功能,如下: 初始化实例变量 收回分配给对象的内存 将自己与其他对象比较 自我归档 在运行时进行方法选择 在运行时提供查询方法的反馈信息 在运行时提供类层级关系的反馈信息 转发消息到其它对象NSObject类(The Root Class) (2/2)2、The NSObject Protocol(根类协议)实际上,这个NSObject类比上面描述的稍微复杂一点。实际的情况是,NSObject类的方法定义被分成了两部分,一部份称为essential(基础),另一部分称为 ancillary(辅助)。基础部分的方法是被Objective-C中其他根类需要的。Essential部分的方法被定义在了NSObject Protocol(协议)中,关于什么是Protocol,你可以简单的理解为是一组方法,这个概念将在后面会详细讲解。而ancillary组中的方法仅仅是NSObject这个类自己会用到的方法,这些方法不需要被其他根类去继承和实现。当然,知道哪些方法属于哪个组实际上并不重要,除非你要自己重写一个属于自己的根类。Static Typing(静态类型) (1/3)1、Static Typing(静态类型)介绍 回想一下之前我们提到的id类型,它可以用在任何对象的类上。Id类型的出现让Objective-C语言在运行时极大地提高了灵活性。(例如,一个一般的List类可以包含任何类型的对象)。这样就组织了编译器检查一个对象是否实现了某个方法。那么要让编译器来检查某个对象是否实现了某个方法怎么办,Objective-C中因为允许你用类名来作为对象的类型。请看下面的例子,实现一个类型的检查 / 编译器检查,myString为NSString类NSString *myString = anObject; / 现在,编译器检查NSString类有没有length方法int len = myString length;Static Typing(静态类型) (2/3)2、Type Introspection(类型的自查) 静态的类型也不总是合适的。例如,当你在一个列表或者其它类似的结构中存储很多不同类型的对象的时候。在此种情况下,如果你想发一些某个类型的对象才能相应的消息,你就需要手动去做类型的检查。NSObject类提供了一个方法可以帮你做这件事,isMemberOfClass方法,请看如下代码: if (namedObject isMemberOfClass: specificClass = YES) / code here 上述代码中,如果namedObject是specificClass类子类的对象,将返回false结果,因为isMemberOfClass是精准匹配。如果你仅仅是想知道namedObject是不是specificClass类的子孙的对象,那还有一个方法可以满足你,它就是isKindOfClass方法,请看如下代码: if (namedObject isKindOfClass: specificClass = YES) / code here 当然,还有一些其它的方法来确定namedObject对象和specificClass类的关系,我们将在后面的Advanced Messaging(高级消息)中再予以讨论。Static Typing(静态类型) (3/3)3、Referring to Instance Variables(关于实例变量) 就像你下面看到的那样,类中,通常会定义实例变量,也称为类的属性,当你需要的时候,你可以将属性设置为public。这样设置意味着,其它对象或者代码段可以用标准的C语言中存取结构体变量的方法来存取类中的实例变量,用操作符”-”就可以实现。要这么做,对象必须是静态类型的,而不能是id类型的。 Bar *bar = foo getBar; int c = bar-value * 2; / value是bar对象的实例变量(Bar类的属性) 通常情况下,在一个类的外面直接访问类的实例变量是一种不好的编程习惯,除非是某些特殊的情况,比如比较注重性能的应用。代替直接访问实例变量的方式是,定义一些被称作accessors(存取器)的方法来设置实例变量的值或者获取实例变量的值。请看如下代码: - (int) value return value; - (void) setValue: (int) newValuevalue = newValue; 上面的代码就是get和set方法,成为存取器。虽然上面的代码没有写出来,但实际上get和set方法还能做很多其它的操作。存取器的使用可以让类外面的代码完全不清楚类里面到底执行了什么样的操作。这种封装形式可以让大型应用的开发变得更加容易维护。Working with Class objects(运用类对象) (1/2)1、Class objects(类对象) 在Objective-C中,各种类本身被视作很多不同的对象,这种特殊的对象被称作类对象。然而,类对象不拥有它们自己定义的实例变量(属性),而类对象也不能被用户去创建或者销毁。它们可以响应被称作类方法的方法,请看如下代码: id result = SomeClassName doSomething; 类对象可以响应自己定义的类方法,就如上面的SomeClassName类可以响应doSomething方法。也可以响应自己父类的类方法,但不允许重写继承过来的父类的类方法。你可以在运行时获取到一个与对象同类型的类的类对象,类对象是一个”Class”类的对象。请看如下代码: / 下面三个stringClass1-3的值都一样id stringClass1 = stringObject class;Class stringClass2 = stringObject class;id stringClass3 = NSString class;通过重写从NSObject中继承来的version方法,你可以给类定义一个版本号version number。int versionNumber = NSString version;这样,开发者就可以正确选择合适的版本的类了。Working with Class objects(运用类对象) (2/2)2、Locating Classes Dynamically(动态分配类) 在Objective-C中,类名是全局可见而且是唯一的。如果在编译时不清楚类名,可以在运行时通过一个字符串来得到类名。我们可以通过NSClassFromString函数通过一个字符串得到一个类对象(class object),请看如下代码: if (anObject isKindOf: NSClassFromString(SomeClassName) = YES) / do something .如果字符串存储了一个非法的类名,NSClassFromString函数将返回一个nil对象。类名、全局变量、函数(注意不是类中的方法)存在相同的命名空间,所以在相同的命名空间中永远不会出现两个相同的名字。Naming Constraints and Conventions(命名规则和 (1/1)1、命名规则和命名习惯下面列出所有的Objective-C中独有的命名规则。 全局变量、函数名、类名是不可以重复的。 一个类中的方法名可以与其它类中的方法重名。 一个类中的实例变量可以与其它类中的实例变量重名。 一个类别名(class category)可以和另一个类别名相同。 一个实例方法(instance method)和一个类方法(class method)可以有相同的名称。 一个协议(protocol)的名字可以和其它类、类别相同。 一个方法可以和一个实例变量(instance variable)重名。 除了这些必须遵守的规则,在编程中还有很多约定俗成的习惯,这些习惯可以让你的代码更具可读性并且可以帮你避免一些命名的冲突。这些习惯对于Objective-C语言来说是很必要的,因为Objective-C语言并没有提供像Java或其它语言中的命名空间分区的功能。下面将一些重要的习惯列出来: 类名、类别名、协议名首字母大写。 方法、实例变量首字母小写。 名称中的第二个单词开始,单词首字母大写,像这样ThisIsALongName 由框架提供的类名,都用框架名的两个缩写大写字母作为前缀,比如NSArray 由程序员建立的类和方法,需要将下划线作为前缀。比如_SomePrivateClassStrings(字符串) (1/6)1、Strings(字符串)在Objective-C中,处理字符串有两种方法。 第一种方法就是传统C语言中处理字符串的方法,用一个char型的字符数组来表示,在OC中,你需要用STR类型来定义一个字符数组来表示字符串。 第二种方法是依靠NSString类或者继承NSString类的子类来实现,Objective-C的编译器对这种方法的支持很好。使用这种方法创建的字符串对象还可以使用很多NSString类中提供的方法,比如使用类似于printf函数的格式来初始化一个字符串。 NSString类的对象使用了Unicode的编码方式,这种方式使用了16bit的存储方式,可以支持世界上所有的语言。而对于Unicode字符,在Objective-C用Unichar类型来表示,实际上Unichar就是两个字节长度的char,用来代表一个Unicode字符。不过在OC中不可以使用如下方法去定义一个Unichar的字符:unichar a = 国; /因为单引号在C语言中只能用于char可以采用直接写文字编码的方式来初始化,如下:unichar a = 0x0100;如果有很多个unichar怎么办?一个个去查表太麻烦了。可以采取变通的方法:unichar a10;NSString *aString = 一二三四五六七八九十;for (int i = 0; i 10; i+)ai = aString characterAtIndex:i;这样就可以初始化Unichar的变量了。Strings(字符串) (2/6)2、Creating NSString Static Instances(建立NSS NSString的静态实例对象是在编译时就分配了内存的空间。建立静态实例对象需要使用标识符作为前缀,后面跟随双引号这种结构,因为是NSString类的对象,所以定义变量的时候,实际上是一个指针类型的,如下:NSString *w = Brainstorm;上面语句中,w是一个变量名,它指向一个NSString类的对象,这个对象中的内容是” Brainstorm”。Strings(字符串) (3/6)3、NSString +stringWithFormat(NSString类中的+s 类方法stringWithFormat常常用于创建一个NSString类的实例对象,与C语言中的printf函数一样,它接受一些常见的参数。如下:int qos = 5;NSString *gprsChannel;gprschannel = NSString stringWithFormat: The GPRS channel is %d, qos;上面的语句中,最后gprsChannel对象中字符串的值为The GPRS channel is 5让我们再看一个例子:NSString *one;NSString *two;one = Brainstorm;two = NSString stringWithFormat: Our trading name is %, one; 上面语句定义了两个NSString类的对象one和two,其中two = NSString stringWithFormat: Our trading name is %, one 语句中的%中的代表一个对象,这是Objective-C中新增加的,这个%非常实用,常常用于程序的调试,比如下面:NSObject *obj = anObject aMethod;NSLog (The method returned: %, obj); 上面的语句会在控制台(console)输出obj这个对象信息。Strings(字符串) (4/6)4、C String Conversion(C语言字符串转换) 当程序中需要调用C语言的一些函数的时候,常常需要将C语言中的字符串与NSString类的字符串互相做转换。 要将标准C语言的字符串转换成NSString的字符串,用NSString类提供的stringWithCString方法,如下:char *function (void);char *result;NSString *string;result = function ();string = NSString stringWithCString: result; 要将NSString字符串转换成标准C的字符串,用NSString类的cString方法,如下:char *result;NSString *string;string = Hi!;result = string cString;Strings(字符串) (5/6)5、NSMutableString NSString对象中的字符串是不可更改的,这意味着,一但你建立了NSString字符串对象,它的内容就不再可更改,这样做是为了优化代码效率。如果你要修改一个字符串对象,你需要使用NSString的子类NSMutableString类来创建对象。所有使用NSString类的地方都可以用NSMutableString来替代。 对于NSString类来说,修改一个字符串的内容是不可能的,但这对于NSMutableString类来说,非常容易。下面我们用stringWithFormat方法建立一个NSMutableString类的对象:NSString *name = Brainstorm;NSMutableString *str;str = NSMutableString stringWithFormat: Hi!, %, name; 记住:当调用NSString的stringWithFormat方法时,返回的是一个NSString类的对象,当调用NSMutableString的stringWithFormat方法时,返回的是一个NSMutableString类的对象。注意:用”.”结构创建的静态字符串对象永远是不可更改的。 NSMutableString类的对象很少去真正修改一个字符串,大部分情况是根据原有字符串生成一个新的字符串。 NSMutableString类中比较有用的一个方法是appendString(追加),该方法的参数就是需要追加的字符串了。请看如下代码:NSString *name = Brainstorm;NSString *greeting = Hello;NSMutableString *s;s = AUTORELEASE (NSMutableString new);s appendString: greeting;s appendString: , ;s appendString: name;下面的代码的结果与上面是一样的:NSString *name = Brainstorm;NSString *greeting = Hello;NSMutableString *s;s = NSMutableString stringWithFormat: %, %, greeting, name;Strings(字符串) (6/6)6、Loading and Saving Strings(读取和存储字符串) Objective-C中提供了很多种操作字符串的方法,其中有些方法是关于文件操作的。比如将一个字符串存储到文件中,或者从文件中的内容写入到字符串里。 将一个字符串的内容写到文件中,使用writeToFile:atomically:方法,代码如下:#include Int main (void) CREATE_AUTORELEASE_POOL(pool); NSString *name = This string was created by GNUstep; if (name writeToFile: /home/nico/testing atomically: YES) NSLog (Success); else NSLog (Failure); RELEASE(pool); return 0; writeToFile:atomically:方法返回YES时成功,返回NO时则失败。如果atomically(自动)标志是YES,系统首先会将字符串的内容写入到一个临时文件中,当写入成功后,才会将临时文件重命名为程序中指定的名称。这样做是为了防止删除上一版本的文件,这个功能满实用哦。 将一个文件的内容读进一个字符串中,要使用stringWithContentsOfFile:方法,下面的实例代码将/home/Brainstorm/test文件中的内容读进字符串: #include Int main (void) CREATE_AUTORELEASE_POOL(pool); NSString *string; NSString *filename = /home/nico/test; string = NSString stringWithContentsOfFile: filename; if (string = nil) NSLog (Problem reading file %, filename); /* * * */ /* */ RELEASE(pool); return 0; 3、 对象的内存Initializing and Allocating Objects(对象的内 (1/4)1、对象的内存分配和初始化 与大多数面向对象语言不同,Objective-C将对象的内存空间分配(allocation)和对象的初始化(initialization)分成了两个独立的步骤。特别地,每一个类都提供了一个类方法(无需实例化成一个对象就可以调用)+alloc可以给一个新的对象分配内存空间。但是初始化确是一个实例方法(只有对象才可以调用),而非类方法。按照惯例,通常初始化的方法是-init。那么创建一个对象的通常方法见如下代码:id newObj = SomeClass alloc
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 【正版授权】 ISO 37114:2025 EN Sustainable cities and communities - Appraisal framework for datasets and data processing methods that create urban management information
- 【正版授权】 ISO 22932-8:2025 EN Mining - Vocabulary - Part 8: Extraction
- 【正版授权】 ISO 10545-23:2025 EN Ceramic tiles - Part 23: Determination of elastic modulus for glazed and unglazed ceramic tiles,substrate and glaze layer
- 【正版授权】 ISO 12231-1:2025 EN Digital imaging - Vocabulary - Part 1: Fundamental terms
- 【正版授权】 IEC 60245-5:1994 FR-D Rubber insulated cables - Rated voltages up to and including 450/750 V - Part 5: Lift cables
- 校园防病安全知识培训课件
- 北仑驾校理论知识培训课件
- 护理常规应聘考试试题及答案
- 精力集中测试题及答案
- 沙盘模拟考试试题及答案
- 医院安保课件
- 文印员考试题库及答案
- 2025年涂料行业研究报告及未来发展趋势预测
- 2025河北唐山某国有企业单位招聘劳务派遣工作人员44人笔试参考题库附带答案详解(10套)
- 留疆战士考试题库及答案
- 班主任与家长沟通课件
- 赏识你的学生
- 哲学导论(完整版)
- 合成孔径雷达
- 北师大版数学四年级下册全册教案设计
- 汉语拼音发音表(适合初学者和老年人)
评论
0/150
提交评论