Objective-C 是一种简单的计算机语言,可用于设计复杂的面向对象程序。 Objective-C 扩展了标准ANSI C 语言,添加了一些定义类、方法和其他结构的语法,并改进了类的动态扩展。
重要提示:本文档不教授任何有关C 语言的内容。如果您还不熟悉C 语言,那么在阅读本文之前您应该先了解C 语言的基础知识。
如果您已经熟悉C 语言,并且之前用面向对象语言编写过程序,那么以下内容将帮助您学习Objective-C 的基本语法。很多传统的面向对象思想,比如封装、继承、多态等都会在Objective-C中得到体现。它们之间存在一些重要的差异,但本文将提及这些差异,并在需要时提供更多详细信息。
Objective-C:C 语言的超集
Objective-C 是ANSI 版本的C 语言的超集,支持与C 相同的基本语法。使用C 代码,您可以定义头文件和源文件,以将公共声明与详细实现代码分开。 Objective-C 头文件表1-1 下列出了扩展。
表1-1 Objective-C 代码的文件扩展名文件类型
扩展名
文件类型字;字体大小:13px;垂直对齐:中间;右边框:rgb(155,179,205) 1px 实心; PADDING-TOP:0.66em'范围=行。H
头文件。头文件包含类、类型、函数和常量的声明。
.米
源代码文件。这是源代码文件的典型扩展,可以包含Objective-C 和C 代码。毫米
源代码文件。使用此扩展的源文件除了Objective-C 和C 代码之外还可以包含C++ 代码。此扩展仅用于Objective-C 代码中引用的C++ 类和属性。当您想在代码中包含头文件时,可以使用#import指令。它更像#include,只不过它必须确保同一文件不能被包含多次。 Objective-C 示例和文档更喜欢#import,并且您的代码也应该这样做。
种类
与大多数其他面向对象语言一样,Objective-C 中的类也提供了用行为封装某些数据的基本结构。对象是类的运行实例,包含类中声明的变量实例的内存中副本以及指向类方法的指针。
Objective-C 中类的定义需要两个明显的部分:接口和实现。接口部分包含类的声明、定义的成员变量以及与该类关联的方法。接口通常位于.h 文件中。实现部分包含类方法的实际代码。实现通常在.m 文件中。
图1-1 显示了声明MyClass 类的语法,该类继承自Cocoa 的基类NSObject。此类的声明以@interface指令开始,以@end指令结束。类名后面(用冒号分隔)是父类名。类的实体变量(有时称为ivars,在其他一些语言中称为成员变量)在用大括号({ 和})括起来的代码块中声明。实体变量后面是类方法声明的列表。每个实体变量和方法都以分号结束。
图1-1 定义类
提示:该接口只声明方法,类也可以声明属性。有关属性的更多信息,请参阅“声明属性”。
Objective-C 支持包含对象的强类型和弱类型变量。声明变量时,强类型变量包含类名,弱类型变量使用类型id 而不是对象。弱类型变量经常在集合等类中使用,其中集合中对象的实际类型可能未知。如果您使用过强类型语言,您可能会认为使用弱类型会导致问题,但在Objective-C 程序中它们实际上提供了很大的灵活性和更大的动态性。
下面的例子展示了强类型和弱类型变量的声明格式: MyClass*myObject1;//strong类型idmyObject2;//弱类型
请注意第一个语句中的*。在Objective-C 中,对对象的引用称为指针。如果您对指针没有清晰的了解,请不要担心,您不必成为Objective-C 编程的指针专家。您只需要记住在声明强类型对象时在变量名前添加* 即可。弱类型id 本身就是一个指针。
方法和通讯
Objective-C 中的类可以声明两种类型的方法:实体方法和类方法。实体方法是可以在该特定类的实例上执行的方法。也就是说,在调用实体方法之前,必须先创建该类的实例。另一方面,类方法不需要创建实例。当然,可以在实例创建后调用。
方法声明由方法的类型标识符、返回值类型、一个或多个签名关键字、参数类型和名称信息组成。图1-2展示了实体方法insertObject:atIndex:的声明格式。
图1-2 方法声明语法
声明以减号(-) 开头,用于指示这是一个实体方法。该方法的实际名称(insertObject:atIndex:)是所有签名关键字(包括冒号)的串联。冒号声明当前参数。如果方法没有参数,则可以省略第一个签名关键字。在此示例中,该方法有两个参数。
当您想要调用此方法时,您可以通过与对象通信来实现。通信内容为方法签名和方法所需的参数信息。
消息包含在方括号([ 和])中。方括号内,左边是接收信息的对象,右边是信息(包括信息所需的参数)。例如,要将消息insertObject:atIndex发送到名为myArray 的对象,您可以使用以下语法: [myArrayinsertObject:anObjectatIndex:0];
为了避免声明多个局部变量来保存临时结果,Objective-C 允许您嵌套信息。每个嵌套消息的返回值可以用作参数、目标或其他消息。例如,您可以用信息替换前面示例中使用的任何变量。因此,如果您有一个名为myAppObject 的对象,该对象具有访问数组对象和将对象插入数组的方法,则可以像这样编写前面的示例: [[myAppObjecttheArray]insertObject:[myAppObjectobjectToInsert]atIndex:0];
Objective-C 还提供使用句点来调用访问器方法。访问器方法获取和设置对象的状态。典型格式为-(type)propertyName 和-(void)setPropertyName:(type)。使用句点语法,您可以将前面的示例重写为: [myAppObject.theArrayinsertObject:[myAppObjectobjectToInsert]atIndex:0];
您还可以使用句点语法进行分配:myAppObject.theArray=aNewArray;
用不同的语法编写更容易,[myAppObject setTheArray:aNewArray];
尽管前面的示例将信息发送到类的实例,但您也可以将信息发送到类本身。当您想要与类通信时,您指定的方法必须定义为类方法,而不是实体方法。
通常,您使用类方法来创建类的新实例,或访问有关该类的一些共享信息。除了一处不同之外,类方法的声明语法与实体方法的声明语法完全相同。使用加号(+) 而不是减号(-) 作为方法类型标识符。
下面的示例说明如何使用类方法作为类的工厂方法。在此示例中,方法数组是NSArray 类(继承自NSMutableArray)的类方法,用于分配和初始化该类的新实例并将其返回给代码。 NSMutableArray*myArray=nil;//nil 相当于NULL//创建一些新数组,并将它们赋给变量myArray。 myArray=[NSMutableArrayarray];
清单1-1 显示了上例中MyClass 类的实现代码。与类的声明一样,类的实现是通过两个编译指令来标识的- 这里是@implementation 和@end。这些指令提供了编译器定位相应类的封闭方法所需的范围信息。方法声明必须与接口中相应的声明匹配,不包括代码块中的内容。
清单1-1 类的实现@implementationMyClass-(id)initWithString:(NSString*)aName{self=[superinit];if(self){name=[aNamecopy];}returnself;}+(MyClass*)createMyClassWithString(NSString*)aName{return[[[selfalloc]initWithString:aName]autorelease];}@end
#p#字幕#e#
属性声明
声明属性是声明和简单实现访问器方法的便捷替代方法。
在类接口中,可以包含属性声明和方法声明。基本定义使用@property 编译器指令,后跟类型信息和属性名称。您还可以自定义配置属性,例如定义访问器方法的执行方式。以下示例显示了一个简单属性的声明:@propertyBOOLflag; @property(copy)NSString*nameObject; //赋值时复制对象。 @property(readonly)UIView*rootView;//声明一个只读方法
每个可读属性都指定一个与该属性同名的方法。每个可写属性都以setPropertyName 格式指定一个附加方法,属性名称的第一个字母大写。
在您的类实现中,您可以使用@synthesize pragma 来要求编译器根据声明的规范创建方法: @synthesizeflag; @synthesizenameObject; @synthesizerootView;
如果您愿意,您可以将@synthesize 语句组合成一行:@synthesizeflag,nameObject,rootView;
实际上,属性减少了您必须编写的冗长代码的数量。由于大多数访问器方法都以类似的方式实现,因此属性消除了为类中公开的每个属性实现读取和写入方法的重复。相反,您只需指定要使用该属性的行为,实际的读写方法将在编译时生成。
要了解如何在类中声明属性,请参阅Objective-C 编程语言中的“声明属性”。
细绳
作为C 语言的超集,Objective-C 支持与C 语言相同的指定字符串约定。换句话说,字符用单引号括起来,字符串用双引号括起来。然而,Objective-C 框架通常不使用C 风格的字符串。它们将字符串作为NSString 对象传递。
NSString 类提供了一个封装字符串的对象,它具有您想要的所有优点,包括任意长度字符串的内存管理、Unicode 支持、printf 样式的格式化工具集等等。由于此类字符串非常常见,因此Objective-C 提供了从常量创建NSString 对象的快捷方式。要使用此快捷方式,您必须在普通双引号字符串前面添加@ 符号,如下例所示:NSString*myString=@'MyString
';NSString*anotherString=[NSStringstringWithFormat:@'%d%@',1,@'String'];//根据C风格字符串创建Objective-C字符NSString*fromCString=[NSStringstringWithCString:'ACstring'encodingNSASCIIStringEncoding];
协议
协议声明的方法可以由任何类实现。协议本身没有类。它们只是定义一个其他对象可以可靠实现的接口。当您在类中实现协议方法时,您可以说您的类符合该协议。
协议经常用于指定委托对象的接口。查看协议、委托和其他对象之间交互的最佳方法是查看示例。
UIApplication 类实现应用程序所需的行为。它不会强制您子类化UIApplication 来接收有关当前应用程序状态的简单通知。相反,UIApplication 类通过调用其分配的委托对象上的特定方法来发送这些通知。实现UIApplicationDelegate 协议方法的对象可以接收这些通知并提供适当的回复。通过在继承自的类后面用“”包裹协议名称来指定您的类遵循或采用的协议。您不必声明如何实现该协议。 @interfaceMyClass:NSObject{}@end
协议的声明看起来类似于类的接口。不同的是协议没有父类,不能定义实体变量。以下示例显示了具有一种方法的简单协议:@protocolMyProtocol-(void)myProtocolMethod;@end
在委托协议的许多示例中,采用协议类似于实现协议中定义的方法。某些协议要求您明确声明您支持哪些协议,并且协议可以指定必需的和可选的方法。然而,当您将开发推进到更深的层次时,您应该花更多的时间来学习协议以及如何使用它们——Objective-C 编程语言中的“协议”。
更多信息
以上内容主要是让大家熟悉Objective-C语言的基础知识。此处介绍的主题涵盖了您在阅读文档时最有可能遇到的语言功能。
#p#字幕#e#