Objective-C 扩展


类扩展与类别有一些相似之处,但它只能添加到在编译时拥有源代码的类(该类与类扩展同时编译)。

类扩展声明的方法是在原始类的实现块中实现的,因此您不能在框架类上声明类扩展,例如 Cocoa 或 Cocoa Touch 类(如 NSString)。

扩展实际上是没有类别名称的类别。它通常被称为匿名类别

声明扩展的语法使用@interface关键字,就像标准的Objective-C类描述一样,但不指示任何从子类的继承。相反,它只是添加括号,如下所示 -

@interface ClassName ()

@end

扩展的特点

  • 不能为任何类声明扩展,只能为我们具有源代码原始实现的类声明扩展。

  • 扩展是添加仅特定于类的私有方法和私有变量。

  • 即使继承的类也无法访问扩展内声明的任何方法或变量。

扩展示例

让我们创建一个具有扩展名的 SampleClass 类。在扩展中,我们有一个私有变量internalID。

然后,我们有一个 getExternalID 方法,它在处理完内部 ID 后返回外部 ID。

该示例如下所示,这在在线编译器上不起作用。

#import <Foundation/Foundation.h>

@interface SampleClass : NSObject {
   NSString *name;
}

- (void)setInternalID;
- (NSString *)getExternalID;

@end

@interface SampleClass() {
   NSString *internalID;
}

@end

@implementation SampleClass

- (void)setInternalID {
   internalID = [NSString stringWithFormat: 
   @"UNIQUEINTERNALKEY%dUNIQUEINTERNALKEY",arc4random()%100];
}

- (NSString *)getExternalID {
   return [internalID stringByReplacingOccurrencesOfString: 
   @"UNIQUEINTERNALKEY" withString:@""];
}

@end

int main(int argc, const char * argv[]) {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   SampleClass *sampleClass = [[SampleClass alloc]init];
   [sampleClass setInternalID];
   NSLog(@"ExternalID: %@",[sampleClass getExternalID]);        
   [pool drain];
   return 0;
}

现在,当我们编译并运行该程序时,我们将得到以下结果。

2013-09-22 21:18:31.754 Extensions[331:303] ExternalID: 51

在上面的例子中,我们可以看到internalID并没有直接返回。我们在这里删除了 UNIQUEINTERNALKEY,只将剩余的值提供给 getExternalID 方法。

上面的例子只是使用了一个字符串操作,但是它可以有很多功能,比如加密/解密等等。