Objective-C 类别(Categories)

有时,您可能会发现希望通过添加仅在某些情况下有用的行为来扩展现有类。为了将这种扩展添加到现有类中,Objective-C 提供了类别(categories)和扩展(extensions)。

如果您需要将方法添加到现有类中,或者添加功能以使其更容易在您自己的应用程序中执行某些操作,最简单的方法是使用类别。

声明类别的语法使用 @interface 关键字,就像标准的 Objective-C 类描述一样,但不表示从子类继承。相反,它在括号中指定类别的名称,如下所示:

  1. @interface ClassName (CategoryName)
  2. @end

类别特征

  • 可以为任何类声明类别,即使您没有原始实现源代码。
  • 在类别中声明的任何方法都将可用于原始类的所有实例以及原始类的任何子类。
  • 在运行时,由类别添加的方法和由原始类实现的方法没有区别。

现在,让我们来看一个实例类别实现。让我们向 CocoaNSString 添加一个类别。此类别将使我们能够添加一个新方法 getCopyRightString,该方法有助于我们返回 Copyright 版权字符串。如下所示:

  1. #import <Foundation/Foundation.h>
  2. @interface NSString(MyAdditions)
  3. +(NSString *)getCopyRightString;
  4. @end
  5. @implementation NSString(MyAdditions)
  6. +(NSString *)getCopyRightString {
  7. return @"Copyright cankaoshouce.com 2021";
  8. }
  9. @end
  10. int main(int argc, const char * argv[]) {
  11. NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
  12. NSString *copyrightString = [NSString getCopyRightString];
  13. NSLog(@"Accessing Category: %@",copyrightString);
  14. [pool drain];
  15. return 0;
  16. }

结果如下:

  1. 2022-07-07 21:19:12.125 Categories[340:303] Accessing Category: Copyright cankaoshouce.com 2021

即使类别添加的任何方法都可用于该类及其子类的所有实例,您仍需要在希望使用其他方法的任何源代码文件中导入类别头文件,否则会遇到编译器警告和错误。

在我们的实例中,因为我们只有一个类,所以我们没有包含任何头文件,在这种情况下,我们应该包含头文件,如上所述。