菜鸟学iPhone开发-Objective-C,转---下

说明,这是网友翻译的一篇总结Objective‐C语法的文章,我觉得原文写得不错,翻译得也可以,所以直接放到这里给大家看了。全文有点长,所以分成三部分,这是第三部分。

完整版中文PDF文件下载可点击 这里

====================================== 分隔线 ====================================

日志记录

  在Objective-C中,将日志信息输出到控制台是非常简单的。实际上NSLog()函数很像C语言里面的printf()函数,除了要用一个%@符号代表一个对象。

  NSLog ( @"The current date and time is: %@", [NSDate date] );

  你可以将一个对象的信息作为日志在控制台输出。NSLog函数调用该对象的description方法,并且将这个方法返回的NSString打印到控制台。你可以在你的类中重写这个方法以返回你自定义的字符串。

属性(Properties

  前面我们写了caption和author的访问方法,你可能也注意到了,那些代码很简单,应该可以写成具有更普遍意义的形式。属性是Objective-C的一个特性,它允许我们自动生成访问器,同时还有其它方面的好处。我们用属性来改写一下Photo类。

之前的代码看上去是这样的:

  #import <Cocoa/Cocoa.h>

  @interface Photo : NSObject {

    NSString* caption;

    NSString* photographer;

  }

  - (NSString*) caption;

  - (NSString*) photographer;

  - (void) setCaption: (NSString*)input;

  - (void) setPhotographer: (NSString*)input;

  @end

  用属性改写后的代码看上去是这样的:

  #import <Cocoa/Cocoa.h>

  @interface Photo : NSObject {

    NSString* caption;

    NSString* photographer;

  }

  @property (retain) NSString* caption;

  @property (retain) NSString* photographer;

  @end

  @property是Objective-C语言的一个指令,通过它声明属性。带括号的”retain”指示设置器(setter)要保留输入值,该行后面的是指定属性的类型以及名称。下面我们看看这个类的实现部分:

  #import "Photo.h"

  @implementation Photo

  @synthesize caption;

  @synthesize photographer;

  - (void) dealloc

  {

    [caption release];

    [photographer release];

    [super dealloc];

  }

  @end

  @synthesize指令为我们主动生成了setter和getter,所以我们必须要做的就只有实现dealloc方法了。只有当访问器不存在的时候,@synthesize才会自动生成访问器,所以,即使是使用@synthesize声明了一个属性,你仍然可以实现自定义的getter和setter。编译器只会自动生成你没有自定义的方法。关于属性的声明还有很多选项,但是它们超出了本指南的范围。

在Nil上调用方法

  在Objective-C中,nil对象的作用等同于很多其他语言的NULL指针。不同的地方在于,在nil上调用方法不会导致程序崩溃或抛出异常。这种技术被用在很多地方,但是对于我们来讲,最主要的就是我们不用在调用一个对象的方法之前检查该对象是否为空。如果你调用了一个nil对象的方法并且该方法有返回值的话,你会得到一个nil返回值。我们也可以用它来稍微改进一下我们的dealloc方法:

  - (void) dealloc

  {

    self.caption = nil;

    self.photographer = nil;

    [super dealloc];

  }

  可以这样做是因为当我们将nil赋值给一个实例变量,设置器(setter)会释放旧对象并且保留(retain)nil对象。这种做法对于dealloc来说更好一些,因为这样做避免了让变量指向一个随机的数据,而这个数据又恰好是另外一个对象。注意,我们在这里使用了self.<var>语法,这表示我们使用的是setter,它会进行内存管理。如果我们仅仅是直接设置值,像下面这样,那就会产生内存泄露:

  // incorrect. causes a memory leak.

  // use self.caption to go through setter

  caption = nil;

类目(Category

  类目是Objective-C中最有用的一个特性。实质上,类目允许你为一个已存在的类添加一些方法而不用子类化该类,也不需要你了解该类的实现细节。这是特别有用的,因为你可以给一个内建的对象添加方法。当你想在你的应用程序里面给所有NSString类型的实例添加一个方法,你只需要添加一个类目,而不需要通过定义一个子类来添加该方法。比如,我想给NSString添加一个方法以判断它是不是一个URL,写法就像这样:

  #import <Cocoa/Cocoa.h>

  @interface NSString (Utilities)

  - (BOOL) isURL;

  @end

  这很像一个类的声明。不同的地方在于后面没有列出父类,并且在括号里面写了类目的名称。类目的名字可以随便取,但是最好能表达出你在类目中包含的方法所要做的事。

下面是一个实现。切记,这不是很好的检查URL的方法。我们只是为了说清楚类目的概念。

  #import "NSString-Utilities.h"

  @implementation NSString (Utilities)

  - (BOOL) isURL

  {

    if ( [self hasPrefix:@"http://"])

      return YES;

    else

      return NO;

  }

  @end

  现在,你可以使用NSString的这个方法了,下面的代码会在控制台打印“string1 is a URL”:

  NSString* string1 =@"http://pixar.com/";

  NSString* string2 =@"Pixar";

  if ( [string1 isURL] )

    NSLog (@"string1is a URL");

  if ( [string2 isURL] )

    NSLog (@"string2is a URL");

  与子类不同,你不能通过类目来添加实例变量。但是你能通过类目重写(override)类中已经存在的方法,当然,重写的时候要特别小心。记住,当你通过类目更改一个类的时候,这个更改会影响你这个应用程序中所有这个类的实例。

  总结

  本文介绍了Objective-C基本知识。就像你看到的一样,这个语言学习起来非常简单。它没有很多特殊的语法,并且许多规范也在Cocoa中被多次使用。如果你喜欢上面那些例子,你可以下载后面的工程然后察看它的源代码。

  LearnObjectiveC Xcode 3.0Project (56k)

  http://cocoadevcentral.com/downloads/LearnObjectiveC-20080414a.zip

----------------------------------------------------分隔线----------------------------------------------------------

参考资料/扩展阅读

1. 《Objective-C基础教程》,Mark Dalrymple & Scott Knaster 著,人民邮电出版社,2009;

2. 《The Objective-C 2.0 Programming Language》,苹果公司官方文档。