代码改变世界

学习Objective-C--第六天

2011-06-17 17:05  Paul Wong  阅读(8535)  评论(11编辑  收藏  举报

教程详细:

      技术:Objective-C    难度:初学者     完成时间:20-30分钟

  在今天的教程里,我们将会学习到类别,以及如何使用类别来扩展Cocoa-Touch类的功能。这是我们学习Objective-C系列的最后一章了,就让我们也会回顾一下目前所学到的知识,还有,探讨一下日后开发Objective-C或iphone应用程序的一些技巧。

类别

      那么,什么是类别呢?大量的Objective-C系列教程会忽略掉类别,这是一个非常有用的语言功能。通过消除不必要的子类,类别有助于保持代码的清洁。从我们已经了解到的,如果我们有一个NSString对象,然后要添加一些函数去做一些事情,例如添加一个可以把字符串中’a’替换成’4’,这样我们可以继承NSString并且添加自己的方法。当我们创建了Car类,我们也可以看到这子类。之前我过叫大家在这教程的最后,创建这样的一个Car子类,所以你可以在基类添加函数了,但在某些情况下,类别提供一个很好的方法去为一个类添加额外的方法:

   类别允许我们为一存在的类添加方法,这样,我们程序中所有类的实例可以获得这样的功能了。例如,我们有100个NSString对象在应用程序里,但你想拥有一个自定义子类,所以每个NSString就得拥有一个额外的方法了(例如reverseString)。有了类别,我们可以轻松地把方法加进类别里,并且所有的实例会允许被使用新方法。语法是和子类的很不相同的,并且类别不会允许你去使用实例变量。然而,方法重写是允许的,但这要慎用,不到万不得已之时勿用。

语法

   类别的语法形式和类相似,他们中也分别有一个接口和一个实现。接口看起来是这样的:

   1:  @interface ClassNameHere (category)   
   2:    
   3:  // method declaration(s)   
   4:    
   5:  @end   
   6:    
   7:  The implementation looks like this;   
   8:    
   9:  @implementation ClassNameHere (category)   
  10:    
  11:  // method implementation(s)   
  12:    
  13:  @end 

举例

   很简单对吧?好吧,让我们看看一个例子吧。我们将要创建一个用来实现string反转的方法。虽然这方法没多大实际用处,但用来做什么并不是重点。你应该已经知道接口的形式了,但这已经存在的了:

   1:  @interface NSString (reverse)   
   2:    
   3:  -(NSString *) reverseString;   
   4:    
   5:  @end  

那怎样创建实现呢?

   1:  @implementation NSString (reverse)   
   2:    
   3:  -(NSString *)reverseString {   
   4:    
   5:  }   
   6:    
   7:  @end 

  接下来,我们将需要添加一些代码来让string反转。由于我们将为NSString类添加方法,我们得自我引用字符串了。现在,为了反转字符串,我们需要一个新的临时字符串对象。我们会用一个循环去反转这字符串,每次寻找一个字符添加到反转字符对象上。代码如下:

   1:  int length = [self length];   
   2:  NSMutableString *reversedString;   
   3:    
   4:  reversedString = [[NSMutableString alloc] initWithCapacity: length];   
   5:    
   6:  while (length > 0) {   
   7:      [reversedString appendString:[NSString stringWithFormat:@"%C", [self characterAtIndex:--length]]];   
   8:  }   
   9:    
  10:  return [reversedString autorelease]; 

  这种方法是相当简单的,我们通过每次循环反转字符串中的字符。我们追加使用stringWithFormat和字符标识符。当我们调用这方法,不仅返回长度整数,并且从字符串删除它,循环是沿着字符串进行的哟。

  如果是顺利的话,所有的NSString已经在我们项目中了,现在你可以知道为什么类别这么好用吧。

使用我们的例子

    好了,现在我们的 NSString对象都应该有reverseString方法了,回顾一下吧,我们的代码是这样的:

   1:  @interface NSString (reverse)   
   2:    
   3:  -(NSString *) reverseString;   
   4:    
   5:  @end   
   6:    
   7:  @implementation NSString (reverse)   
   8:    
   9:  -(NSString *)reverseString {   
  10:      int length = [self length];   
  11:      NSMutableString *reversedString;   
  12:    
  13:      reversedString = [[NSMutableString alloc] initWithCapacity: length];   
  14:    
  15:      while (length > 0) {   
  16:          [reversedString appendString:[NSString stringWithFormat:@"%C", [self characterAtIndex:--length]]];   
  17:      }   
  18:    
  19:      return [reversedString autorelease];   
  20:  }   
  21:    
  22:  @end

   每个代码块(接口和实现)都会在它们自己约定好的文件里。然而,我们命名类别有点不同。我们创建了两个文件:NSString + reverse.h(接口)和NSString + reverse.m(实现)。

   这是一个典型的命名规范,我们在这类里加入一个类别。在我们继续之前,还要记得在项目里引入我们的头文件。所以,你现在的代码看起来会像:

   1:  NSString* testString = @"Just a test";   
   2:    
   3:  [testString reverseString];   
   4:    
   5:  NSLog(@"Reversed: '%@'", testString);

  如果一切按计划进行,这样控制台会输出”Just a test”。

  如果并没有全按照计划进行,检查一下来确保你复制的代码是正确的,并且类别已经引入了头文件(*.h)文件。

  看到了吧,类别真的是挺有用的(特别是对于字符串)。在任何项目中都有广泛的应用,通常我会用在检验上。通过这种方法,我可以保证不用任何复杂子类的情况下只在一个地方验证。

总结系列教程

    今天的结束将代码本系列教程的结束了,回顾以上几个章节,我们提及到的主题如下:

  • 程序设计基础
  • OOP基础知识
  • 类和子类
  • 内存管理
  • 良好的实践
  • 一些标准的命名约定

  我希望您喜欢这个系列,目前如果你只读了本系列中的一两章,那么我建议您从第一天开始读完。在这系列结束之时,你会有足够的信心在你的应用程序中敲代码。

  如果您对本系列有疑问,或者如果您想在Objective-C的另一方面知识开辟一系列教程,请承受时发表评论。

  如果你对Objective-C知识有疑问,无论在项目中,或是工作上,请不要犹豫与我联系,可以通过Twitter或是浏览我主页。

挑战

   本教程暂告一段落了,前面的挑战也将结束。我强烈建议您动起手来建立您的第一个应用程序。提出一个想法和设计方案,用上所有您在本教程系列中学过的知识,好吧,动手吧!

  谢谢您的阅读!

 

系列教程导航

<<学习Objective-C--第五天