在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
本人翻译的Apple Dev Center的技术资料并稍作修改。 转载请注明出处:http://blog.csdn.net/zhyzh2046/ 学习Objective-C:初级读本
Objective-C是一种简单的计算机语言,支持复杂南通的面向对象编程。Objective-C从标准的ANSI C语言扩展而来,并提供了定义类、方法和属性的语法,还有其它结构来促进类的动态扩展。类的语法和设计把部分基于第一种面向对象的编程语言Smalltalk。
如果你有使用面向对象语言的经验,接下来的信息会帮你学习到Objective-C基本的语法。许多传统的面向对象概念,如封装、继承和多态,都会在Objective-C中出现。但是会存在一些重要的不同之处,不过这篇文章会讲解这些不同,而且还可以查到更加详细的信息。
如果你从来没有使用过面向对象语言,在开始之前,至少需要基本理解相关的概念。对象和面向对象结构的使用是设计iPhone程序的基础,而且理解它们是怎样交互的是创建程序的必要条件。使用Objective-C进行面向对象编程中介绍了面向对象概念概述。
要了解关于Objective-C更加详细的信息和语法,请查阅Objective-C程序设计。
Objective-C:C语言的超集 Objective-C是C语言的ANSI版本的超集,支持相同的基础语法。与C语言相同,Objective-C也会定义头文件和源文件,将公共的声明和实现分离。Objective-C头文件使用的文件扩展名列在表1中。
当需要在头文件包含头文件时,可以使用标准的#include预编译指令,但是Objective-C提供了更好的方法。#import指令和#include指令是一样的,除了它能保证相同的文件永远不会被引用多次。Objective-C的示例和文档都建议使用#import,你自己的代码也应该如此。 Strings 作为C的超集,Objective-C在指定字符串时,具有和C一样的约定。换句话说,单个字符使用单引号,字符串会使用双引号包围。但是,大多数Objective-C框架经常不使用C样式的字符串。取而代之,大多数框架将字符串封装在一个NSString对象中。 NSString类是字符串的对象载体,它具有希望的所有优点,包括为处理任意长度的字符串内置的内存管理、支持Unicode、Printf风格的格式化优点等等。但由于一些字符串经常使用,Objective-C提供了一个速记符号从常量创建NSString对象。使用这用速记,你所要做的仅仅是在一个正常的双引号包含的字符串之前加上一个@符号,如下示例:
NSString*myString=@"MyString";
NSString*anotherString=[NSStringstringWithFormat:@"%d%s",1,@"String"]; //CreateanObjective-CstringfromaCstring //从C字符串创建Objective-C字符串 NSString*fromCString=[NSStringstringWithCString:"ACstring"encoding:NSASCIIStringEncoding]; Classes
Objective-C中创建一个类需要截然不同的两个部分:接口和实现。接口部分包含类的声明,还会定义成员变量和与类相关联的方法。实现部分包含类方法的实际实现代码。图1显示了声明一个叫做MyClass的类的语法,它继承了NSObject基类。类声明会以@interface预编译指令开始,以@end指令结束。类名之后(有一个冒号分开)是父类的名称。类的成员变量在大括号包含的代码中声明({和})。在成员变量之后的代码块是类声明的方法列表。每个成员变量和方法的声明之后都要以分号结尾。
图2 类的实现 注意:尽管上述例子中,类的声明部分只声明了一些方法,类是可以在这里声明属性的。关于属性的更多信息,请看“属性”一节。 当使用变量存储对象时,经常会使用指针类型。Objective-C中,强类型和弱类型变量都可以保存对象。强类型指针的变量在声明时必须包含类名。集合类经常使用弱类型指针,因为可能还不知道集合中对象的类型。如果你习惯于使用强类型的编程语言,你可能会认为弱类型变量的使用会产生问题,但是实际上,在使用Objective-C编程时,它会带来极大的便利,同时会带来更好的扩展性。 下面这个例子演示了MyClass类的强类型和弱类型变量的声明:
MyClass*myObject1;//强类型
idmyObject2;//弱类型 Methods
Objective-C语言中的类可以声明两种方法:实例方法和类方法。实例方法的执行者必须是类的一个特定实例。换句话说,在调用实例方法之前,必须先创建一个类的实例,之后必须使用这个实例来调用实际的方法。相比之下,类方法不需要创建类的实例,后面会有详细的解释。
方法的声明由方法类型标识符、返回类型、一个或多个署名关键字和参数的名称、类型信息组成。图3中声明了一个insertObject:atIndex:的实例方法。方法声明的前面加上了一个减法符号(-),这说明这个方法是一个实例方法。方法的实际名称(insertObject:atIndex:)是所有署名关键字串联起来的,包括冒号字符。冒号说明参数的存在。如果方法没有参数,第一个(唯一的)署名关键之后可以忽略冒号。这个例子中,方法含有两个参数。
图3声明方法的语法
当调用一个方法时,要通过"messaging”来通知相应的对象。这个例子中的消息就是方法名和这个方法所需的参数信息。发送到对象的所有消息是动态发送的,因此这有利于Objective-C的多态特征。换句话说,如果子类定义了与父类同名的方法,子类会第一个收到消息,然后可以选择是否要将这个消息转交给它的父类。
消息都是放在方括号([和])中。在方括号中,收消息的对象放在左边,消息(和任何消息需要的参数)放在右边。例如,发送insertObject:atIndex:消息给myArray对象,使用的语法如下:
[myArrayinsertObject:anObjatIndex:0];
为避免声明大量局部变量来存储临时数据,Objective-C支持嵌套消息。每一个嵌套消息的返回值都可以作为另一个消息的参数或者是目标。例如,上例中的任何变量都可以被替换成能得到值的消息。因此,如果有另外一个对象myAppObject,它的方法方法可以访问数组对象,并且有另外一个数组对象,可以将上面的例子写出如下样子:
[[myAppObjectgetArray]insertObject:[myAppObjectgetObjectToInsert]atIndex:0];
尽管前面的例子是向一个类的实例发送消息,还可以向类本身发送消息。当向类发送消息时,调用的方法必须定义成类方法而不是实例方法。可以这样认为:类方法同C++语言中类的静态成员方法有些相似(但又不是完全相似)。
类方法有代表性的用法有,作为工厂方法来创建类的一个新实例,或者用来访问与类相关的一些共享信息。类方法的定义语法与实例方法是完全一样的,只有一点不同。类方法使用加法符号(+),而不是减法符号作为方法的类型标识符。
下面的例子演示了类方法的使用,这里它作为类的工厂方法。在这里,arrayWithCapacity:方法是类NSMutableArray的类方法,他会申请并初始化一个新的类实例并返回它。
NSMutableArray*myArray=nil;//nil本质上与NULL相同
//创建新的数组并赋值给myArray变量 myArray=[NSMutableArrayarrayWithCapacity:0]; Properties
属性
属性是一种便利符号,用来代替存取方法(accessor methods)。属性并不是在类的声明中创建一个新的成员变量。他们仅仅为定义用来访问已经存在的变量的方法指定的快捷方式。类可以使用属性标记来公开成员变量,而不是使用getter和setter方法。类还可以使用属性来公开“virtual”(虚)的成员变量—它是动态计算的一部分数据并且并不实际存储在成员变量中。
实际点说,属性的使用减少了你的冗余代码量。应为大部分存取方法用相似的方式实现,使用属性可以不必为每一个成员变量提供截然不同的getter和setter方法。相反,你可以使用属性的声明指定具体的动作,在编译的时,会根据声明合成实际的getter和setter方法。
因为属性的声明会创建实际的方法,可以和方法的声明一起定义在类的接口中。基本的定义使用@property预编译指令,后边是属性的类型信息和名称。可以使用定制选项配置属性,它定义了存取方法有怎样的行为。下面的例子显示了一些简单的类型声明:
@propertyBOOLflag;
@property(copy)NSString*nameObject;//赋值过程中拷贝对象 @property(readonly)UIView*rootView;//仅创建getter方法 属性的另一个好处是在代码中可以使用点语法来访问他们,如下演示:
myObject.flag=YES;
CGRectviewFrame=myObject.rootView.frame;
尽管上面的例子中的对象和属性的名字很做作,但是他们演示了属性的灵活性。点语法实际上屏蔽了相关一系列方法的调用。每个可读属性由同名的方法支持。每个可写属性由附加的方法setPropertyName:支持,在这里属性名称的第一个字母大写了。(这些方法是属性的实际实现,同时也是可以在没有成员变量支持的类中包含属性定义的原因。)不用属性去实现上面代码完成的功能,你需要编写如下代码:
[myObjectsetFlag:YES];
CGRectviewFrame=[[myObjectrootView]frame];
关于在类中如何声明属性的更多信息,请查阅Objective-C程序设计中”属性”一节。
Protocols and Delegates
协议和代理
协议声明的方法可以被任何一个类实现。协议不是类本身。他们仅定义了其它对象有责任实现的接口。当在自己的类中实现协议的方法时,你的类就是遵守这个协议的。
iPhone OS中,协议经常被用作实现代理对象。代理对象是一个能代表其它对象或与其它对象合作的一个对象。学习协议、代理和其它对象相互影响的最好方法就是从例子中学习。
UIApplication类实现了应用程序所需的功能。不是强制继承UIApplication类来接收一个简单的应用程序当前状态的通知,而是UIApplication类调用赋值给代理对象的方法来分发这些通知。实现了UIApplicationDelegate协议方法的对象可以接收这些通知并提供合适的响应。
协议的声明类似于类接口的声明,有一点不同的是,协议没有父类,并且不能定义成员变量。下面的例子演示了只有一个方法的协议的声明:
@protocolMyProtocol
-(void)myProtocolMethod; @end
很多代理协议中,采用协议只是大概实现了协议中定义的方法。一些协议需要明确声明支持的协议,但是现在假设仅实现方法就足够了。但是,如果想将更多的只是应用到你的开发中,你应该多花些时间来学习协议和他们的使用方法,可以通过查阅Objective-C程序设计中的”协议”一节。
|
请发表评论