佳为好友

转:iPhone开发系列文章(三)-Objective-C语言简介

08-8-19

转:http://blog.csdn.net/zhyzh2046/archive/2008/03/16/2187644.aspx


iPhone开发系列文章(三)-Objective-C语言简介 - zhyzh2046的天地 - CSDNBlog

本人翻译的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中。 

 

表1 Objective-C源代码的文件扩展名
扩展名代码类型
.h头文件。头文件中包含类、类型、函数和常量的声明。
.m源文件。这是源文件的一种典型扩展,可以包含C代码和Objective-C代码。
.mm源文件。这种源文件除了可以包含C代码和Objective-C代码之外,还可以包含C++代码。这种扩展名只能用于你实际引用了C++的类,或者引用了Objective-C的功能。

   

当需要在头文件包含头文件时,可以使用标准的#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 = @"My String "; 
NSString* anotherString = [NSString stringWithFormat:@"%d %s", 1, @"String"]; 

// Create an Objective-C string from a C string 
//从C字符串创建Objective-C字符串 
NSString* fromCString = [NSString stringWithCString:"A C string" encoding:NSASCIIStringEncoding]; 

Classes 


正如大部分其它面向对象语言一样,Objective-C中的类是一个基本的结构体,封装了一些数据以及操作这些数据的动作。对象是类运行时的实例,包含类中声明的成员变量和类方法的指针在内存中的拷贝。

Objective-C中创建一个类需要截然不同的两个部分:口和实现。接口部分包含类的声明,还会定义成员变量和与类相关联的方法。实现部分包含类方法的实际实现代码。图1显示了声明一个叫做MyClass的类的语法,它继承了NSObject基类。类声明会以@interface预编译指令开始,以@end指令结束。类名之后(有一个冒号分开)是父类的名称。类的成员变量在大括号包含的代码中声明({和})。在成员变量之后的代码块是类声明的方法列表。每个成员变量和方法的声明之后都要以分号结尾。 
图1 类的声明


图2显示了上例中MyClass的实现。像类的声明一样,类的实现由两个预编译指令来指示-在这里是@implementation和@end。这些指令定义了范围信息,告诉编译器需要将附上的方法和相关的类联系起来。因此,方法的定义与接口中声明的要匹配,除了代码块的包含。

图2 类的实现

注意:尽管上述例子中,类的声明部分只声明了一些方法,类是可以在这里声明属性的。关于属性的更多信息,请看"属性"一节。

当使用变量存储对象时,经常会使用指针类型。Objective-C中,强类型和弱类型变量都可以保存对象。强类型指针的变量在声明时必须包含类名。集合类经常使用弱类型指针,因为可能还不知道集合中对象的类型。如果你习惯于使用强类型的编程语言,你可能会认为弱类型变量的使用会产生问题,但是实际上,在使用Objective-C编程时,它会带来极大的便利,同时会带来更好的扩展性。

下面这个例子演示了MyClass类的强类型和弱类型变量的声明

MyClass* myObject1; // 强类型
id myObject2; //弱类型

Methods 
方法
 

  

Objective-C语言中的类可以声明两种方法:实例方法和类方法。实例方法的执行者必须是类的一个特定实例。换句话说,在调用实例方法之前,必须先创建一个类的实例,之后必须使用这个实例来调用实际的方法。相比之下,类方法不需要创建类的实例,后面会有详细的解释。

方法的声明由方法类型标识符、返回类型、一个或多个署名关键字和参数的名称、类型信息组成。图3中声明了一个insertObject:atIndex:的实例方法。法声明的前面加上了一个减法符号(-),这说明这个方法是一个实例方法。方法的实际名称(insertObject:atIndex:)是所有署名关键字串联起来的,包括冒号字符。冒号说明参数的存在。如果方法没有参数,第一个(唯一的)署名关键之后可以忽略冒号。这个例子中,方法含有两个参数。
图3 声明方法的语法
当调用一个方法时,要通过"messaging"来通知相应的对象。这个例子中的消息就是方法名和这个方法所需的参数信息。发送到对象的所有消息是动态发送的,因此这有利于Objective-C的多态特征。换句话说,如果子类定义了与父类同名的方法,子类会第一个收到消息,然后可以选择是否要将这个消息转交给它的父类。
 
消息都是放在方括号([和])中。在方括号中,收消息的对象放在左边,消息(和任何消息需要的参数)放在右边。例如,发送insertObject:atIndex:消息给myArray对象,使用的语法如下:
[myArray insertObject:anObj atIndex:0];
为避免声明大量局部变量来存储临时数据,Objective-C支持嵌套消息。每一个嵌套消息的返回值都可以作为另一个消息的参数或者是目标。例如,上例中的任何变量都可以被替换成能得到值的消息。因此,如果有另外一个对象myAppObject它的方法方法可以访问数组对象,并且有另外一个数组对象,可以将上面的例子写出如下样子:
[[myAppObject getArray] insertObject:[myAppObject getObjectToInsert] atIndex:0];
尽管前面的例子是向一个类的实例发送消息,还可以向类本身发送消息。当向类发送消息时,调用的方法必须定义成类方法而不是实例方法。可以这样认为:类方法同C++语言中类的静态成员方法有些相似(但又不是完全相似)。
类方法有代表性的用法有,作为工厂方法来创建类的一个新实例,或者用来访问与类相关的一些共享信息。类方法的定义语法与实例方法是完全一样的,只有一点不同。类方法使用加法符号(+)而不是减法符号作为方法的类型标识符。
下面的例子演示了类方法的使用,这里它作为类的工厂方法。在这里,arrayWithCapacity:方法是类NSMutableArray的类方法,他会申请并初始化一个新的类实例并返回它。
NSMutableArray*   myArray = nil;    // nil 本质上与NULL相同

//创建新的数组并赋值给myArray变量
myArray = [NSMutableArray arrayWithCapacity:0];

 

 

Properties
属性
属性是一种便利符号,用来代替存取方法(accessor methods)。属性并不是在类的声明中创建一个新的成员变量他们仅仅为定义用来访问已经存在的变量的方法指定的快捷方式。类可以使用属性标记来公开成员变量,而不是使用getter和setter方法。类还可以使用属性来公开"virtual"(虚)的成员变量—它是动态计算的一部分数据并且并不实际存储在成员变量中。
 
实际点说,属性的使用减少了你的冗余代码量。应为大部分存取方法用相似的方式实现,使用属性可以不必为每一个成员变量提供截然不同的gettersetter方法。相反,你可以使用属性的声明指定具体的动作,编译的时,会根据声明合成实际的getter和setter方法。
 
因为属性的声明会创建实际的方法,可以和方法的声明一起定义在类的接口中。基本的定义使用@property预编译指令,后边是属性的类型信息和名称。可以使用定制选项配置属性,它定义了存取方法有怎样的行为。下面的例子显示了一些简单的类型声明:
@property BOOL flag;
@property (copy) NSString* nameObject;  // 赋值过程中拷贝对象
@property (readonly) UIView* rootView;  // 仅创建getter方法
 
属性的另一个好处是在代码中可以使用点语法来访问他们,如下演示
 myObject.flag = YES;
 CGRect   viewFrame = myObject.rootView.frame;
 
尽管上面的例子中的对象和属性的名字很做作,但是他们演示了属性的灵活性。点语法实际上屏蔽了相关一系列方法的调用。每个可读属性由同名的方法支持。每个可写属性由附加的方法setPropertyName:支持,在这里属性名称的第一个字母大写了。(这些方法是属性的实际实现,同时也是可以在没有成员变量支持的类中包含属性定义的原因。)不用属性去实现上面代码完成的功能,你需要编写如下代码:
 [myObject setFlag:YES];
 CGRect   viewFrame = [[myObject rootView] frame];
 
关于在类中如何声明属性的更多信息,请查阅Objective-C程序设计中"属性"一节。
 
Protocols and Delegates
协议和代理
 
协议声明的方法可以被任何一个类实现。协议不是类本身。他们仅定义了其它对象有责任实现的接口。当在自己的类中实现协议的方法时,你的类就是遵守这个协议的。
 
iPhone OS中,协议经常被用作实现代理对象。代理对象是一个能代表其它对象或与其它对象合作的一个对象。学习协议、代理和其它对象相互影响的最好方法就是从例子中学习。
 
UIApplication类实现了应用程序所需的功能。不是强制继承UIApplication类来接收一个简单的应用程序当前状态的通知,而是UIApplication类调用赋值给代理对象的方法来分发这些通知。实现了UIApplicationDelegate协议方法的对象可以接收这些通知并提供合适的响应。
 
协议的声明类似于类接口的声明,有一点不同的是,协议没有父类,并且不能定义成员变量。下面的例子演示了只有一个方法的协议的声明:
@protocol MyProtocol
- (void)myProtocolMethod;
@end

 

很多代理协议中,采用协议只是大概实现了协议中定义的方法。一些协议需要明确声明支持的协议,但是现在假设仅实现方法就足够了。但是,如果想将更多的只是应用到你的开发中,你应该多花些时间来学习协议和他们的使用方法,可以通过查阅Objective-C程序设计中的"协议"一节。
+++++

posted on 2012-12-26 10:20 佳为好友 阅读(260) 评论(0)  编辑 收藏 引用 所属分类: UI


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

<2012年12月>
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345

留言簿(1)

随笔分类

搜索

最新评论

评论排行榜