1.面象的读者
在阅读本文之前,应具备使用与C类似的编程语言(如C,C++,JAVA)的一些经验,同时熟悉面向对象编程。
2.ObjC简介
ObjC是以SmallTalk为基础,建立在C语言之上,是C语言的超集。20世纪80年代早期由 Brad J.Cox设计,2007年苹果公司发布了ObjC 2.0,并在iPhone上使用ObjC进行开发。
3.ObjC学习内容
学习的内容主要包括语法和Cocoa框架两部分。本文主要对语法进行介绍。
4.IDE
编写ObjC程序最主要的编译环境是Xcode,它是苹果官方提供的IDE,官网中的SDK包括Xcode,可以通过下载SDK来获得它。但是Xcode只支持MacOS X,所以如果要在其它环境下编写ObjC程序,要使用其它IDE。Linux/FreeBSD用GNUStep,Windows NT5.x(2000,XP)要先安装cywin或mingw,然后安装GNUStep。同时仅仅通过文本编辑器,GCC的make工具也可以用于开发。
注:如果要使用到Cocoa的话,只能在Apple公司的Xcode上。
5.框架
ObjC编程中主要用到的框架是Cocoa,它是MacOS X中五大API之一,它由两个不同的框架组成FoundationKit 和ApplicationKit。 Foundation框架拥有100多个类,其中有很多有用的、面向数据的低级类和数据类型,如NSString,NSArray, NSEnumerator和NSNumber。ApplicationKit包含了所有的用户接口对象和高级类。这些框架本文不做重点介绍,如果要深入了解可以去看Xcode自带的文档。
7.优缺点
每一个语言都有其优缺点,ObjC也不例外,这就要求在选择语言时权衡利弊。对于ObjC,只要善于利用它的优点,你会发现它是一个简单,灵活,高效的语言。以下列举了它的一些特点:
优点:类别、扮演(Posing)、动态类型、指针计算、弹性信息传递、不是一个过度复杂的c衍生语言、可通过Objective-c++与c++结合
缺点:没有命名空间、没有操作符重载、不像c++那样复杂
第二节对C的扩展
3.@符号
@符号是ObjC在C基础上新加的特性之一。常见到的形式有@”字符串”,%@ , @interface,@implement等。@”字符串”表示引用的字符串应该作为Cocoa的NSString元素来处理。@interface等则是对于C的扩展,是ObjC面向对象特性的体现。
注:这里提一个小技巧,只要看到@符号,就可以认为它是对于C的一个扩展。
5.BOOL
BOOL是ObjC中的布尔类型,它和C中的bool有如下区别
BOOL
YES(1),NO(0)
bool
true(!0),false(0)
6.id
这是ObjC新加的一个数据类型,它是一般的对象类型,能够存储任何类型的方法。
3.属性
属性提供了比方法更方便的访问方式。通过property标识符来替代getter和setter方法。使用方法就是在类接口文件中用@property标识符,后面跟着变量的属性,包括 copy, tetain, assign ,readonly , readwrite,nonatomic,然后是变量名。同时在实现文件中用@synthesize标识符来取代getter和setter方法。
@property (copy) NSString* nameObject;
属性的另一个好处就是,可以使用点(.)语法来访问,如下所示:
myObject.flag = YES;
第四节继承
继承的语法如下,冒号后的标识符是需要继承的类。
@interface Circle : NSObject
1.不支持多继承
要注意的是ObjC只支持单继承,如果要实现多继承的话,可以通过类别和协议的方式来实现,这两种方法将在后面进行介绍。
第五节 对象初始化
1.分配与初始化
对象的初始化有两种方法:一种是[类名new], 第二种是[[类名 alloc]init]。这两种方法是等价的,不过,通常的Cocoa惯例是使用alloc和init,而不使用new.一般情况下,Cocoa程序员只是在他们不具备足够的水平来熟练使用alloc和init方法时,才将new作为辅助方法使用。
[[类名alloc]init]有两个动作。alloc是分配动作,是从操作系统获得一块内存并将其指定为存放对象的实例变量的位置。同时,alloc方法还将这块内存区域全部初始化为0。与分配动作对应的是初始化。有如下两种初始化写法。
Car *car = [[Class alloc] init];
写法1
Car *car = [Car alloc];
[car init];
写法2
应该使用第一种写法,因为init返回的对象可能不是以前的那个。
第六节协议
这里的协议是正式协议,相对的还有非正式协议,这在类别一节中有介绍。正式协议是一个命名的方法列表。它要求显式地采用协议。采用协议意味着要实现协议的所有方法。否则,编译器会通过生成警告来提醒你。
1.声明协议
@protocol NSCopying
-(id) copyWithZone:(NSZone *)zone;
@end
2.采用协议
@interface Car : NSObject <NSCopying , NSCoding>
{
// instance variables
}
@end
协议可以采用多个,并且可以按任意顺序列出这些协议,没有什么影响。
3.ObjC 2.0的新特性
ObjC2.0增加了两个新的协议修饰符:@optional和@required,因此你可以像下面这样编写代码:
@protocol BaseballPlayer
-(void)drawHugeSalary;
@optional
-(void)slideHome;
-(void)catchBall;
@required
-(void)swingBat;
@end
因此,一个采用BaseballPlayer协议的类有两个要求实现的方法:-drawHugeSalary和-swingBat,还有3个不可选择实现的方法:slideHome,catchBall和throwBall。
第七节委托
Cocoa中的类经常使用一种名为委托(delegate)的技术,委托是一种对象,另一个类的对象会要求委托对象执行它的某些操作。常用的是,编写委托对象并将其提供给其他一些对象,通常是提供给Cocoa生成的对象。通过实现特定的方法,你可以控制Cocoa中的对象的行为。
通过下面的例子,可以更清楚地理解委托的实现原理。其中A对象需要把一些方法委托给其它对象来实现,例子中就是对象B,B实现了含A对象特定方法的协议ADelegate,从而可以在B中实现A委托的方法。
@protocol ADelegate <NSObject>
- (void)aDelegateMethod;
……
@end
@interface A : NSObject {
……
id <ADelegate> delegate;
}
@property (readwrite, assign) id <ADelegate>delegate;
……
@end
@implementation A
@synthesize delegate;
- (void)aMethod{
[delegate aDelegateMethod];
……
}
@end
A类
@interface B : NSObject <ADelegate>
@end
@implementation B
- (id)init {
……
[[A sharedA] setDelegate:self];
}
- (void)aDelegateMethod{ //B中实现A委托的方法
……
}
…
第八节 类别
类别允许你在现有的类中加入新功能,这些类可以是框架中的类,并且不需要扩充它。
1.声明类别
@interface NSString (NumberConvenience)
-(NSNumber *) lengthAsNumber;
@end
该声明表示,类别的名称是NumberConvenience,而且该类别将向NSString类中添加方法。
2.实现类别
@implementation NSString (NumberConvenience)
-(NSNumber *) lengthAsNumber
{
unsigned int length = [self length];
return ([NSNumber numberWithUnsignedInt: length]);
}
@end
3.局限性
类别有两方面的局限性。第一,无法向类中添加新的实例变量。类别没有位置容纳实例变量。第二,名称冲突,即类别中的方法与现有的方法重名。当发生名称冲突时,类别具有更高的优先级。这点可以通过增加一个前缀的方法解决。
@end
B类
第十节动态识别 (Dynamictypes)
下面是应用动态识别时所用到的方法:
-(BOOL)isKindOfClass: classObj
是否是其子孙或一员
-(BOOL)isMemberOfClass: classObj
是否是其一员
-(BOOL)respondsToSelector: selector
是否有这种方法
+(BOOL)instancesRespondToSelector: selector
类的对象是否有这种方法
-(id)performSelector: selector
执行对象的方法