在Apple发布Xcode7的时候,不仅把Swift编程语言升级到了2.0版本,而且还对Objective-C做了许多提升,包括引入__nonnull/__nullable。其中,对于Objective-C编程语言本身而言,更为有用的便是轻量级泛型。

其中,比较明显的体现就是NSArray、NSDictionary这些容器类都采用了新引入的轻量级泛型。通过轻量级泛型,我们可以非常容易地获取其中的元素,并访问其相印特有的属性和方法。我们举一个简单例子来阐明轻量级线程带来的方便:

    // 不带泛型的情况
NSArray *numArray = @[@, @, @];
int sum = [(NSNumber*)numArray[] intValue] + [(NSNumber*)numArray[] intValue] + [(NSNumber*)numArray[] intValue]; // 使用泛型的情况
NSArray<NSNumber*> *numArray = @[@, @, @];
int sum = [numArray[] intValue] + [numArray[] intValue] + [numArray[] intValue];

我们通过上述例子就能看到轻量级泛型带来的语法上的便利性,即它是一块甜美的语法糖(syntax sugar)。

之前Apple LLVM 6.0对C11标准的泛型——generic selection在Objective-C上支持得还不够良好,但Apple LLVM 7.0上已经能完美支持了。比如下述例子:

    int flag = _Generic(@, NSNumber*:, NSString*:, int:, default:);
NSLog(@"The flag is: %d", flag);

上述代码将成功地输出“The flag is: 1”。

与C11的generic selection所不同的是,Objective-C自带的泛型其本质为covariant type,即协变类型。也就是,其泛型与Java的有些类似。它要求泛型必须是一个Objective-C类类型,即至少为id类型。对于上述NSArray的例子,我们在声明一个Objective-C对象引用时,通过在类名后面添加<NSNumber*>来指明当前NSArray里的元素都是NSNumber*类或其子类类型。这样,我们在访问其元素时可直接访问其intValue方法。

下面我们介绍如何自己定义一个泛型类。其语法描述如下:

@interface    class_name    <    __covariant    type_identifier    >    inherit_expression

这里,class_name就是类名;type_identifier是类型标识符,该标识符可以由程序员自己命名;最后的inherit_expression表示继承某个父类以及/或实现某些协议。

这里引入了一个新的关键字——__covariant,表示后面的type_identifier是一个泛型类型。该泛型类型在声明一个对象时进行具体指明。

下面举一个具体的例子来说明如何具体使用Objective-C泛型。

@interface MyObject<__covariant T> : NSObject
{
@private T obj;
}

@property (nonatomic, retain) T obj;

@end

@implementation MyObject

@synthesize obj;

- (void)dealloc
{
if(obj != nil)
[obj release]; NSLog(@"My object deallocated!");
[super dealloc];
} @end @implementation ViewController - (void)viewDidLoad { MyObject<NSNumber*> *numObj = [[MyObject alloc] init];
numObj.obj = @;
[numObj release]; MyObject<NSString*> *strObj = [[MyObject alloc] init];
strObj.obj = @"Hello, world";
[strObj release];
} @end

上述代码,我们定义了一个MyObject的泛型类,其泛型标识符用T表示。随后,我们用该泛型T定义了一个私有对象obj,并用它作为一个property。

随后,我们在viewDidLoad方法里用MyObject<NSNumber*>声明了一个对象numObj;用MyObject<NSString*>声明了一个strObj对象。我们后面可以直接通过numObj.obj调用intValue来访问其int值;直接通过strObj.obj来调用length方法以获得其字符串长度。

最新文章

  1. Excel 转Latex 及tex表格的处理 总结
  2. iOS解析XML数据
  3. Access denied for user &#39;root&#39;@&#39;localhost&#39; (using password:YES)
  4. POJ1050To the Max(求最大子矩阵)
  5. BZOJ3591: 最长上升子序列
  6. Notepad++快捷键&amp;正则表达式替换字符串&amp;插件
  7. [shell基础]——数组
  8. C# &quot;error CS1729: &#39;XXClass&#39; does not contain a constructor that takes 0 arguments&quot;的解决方案
  9. LeetCode44 Wildcard Matching
  10. LeetCode Implement Trie (Prefix Tree) (实现trie树3个函数:插入,查找,前缀)
  11. javascript 实现jsonp
  12. KeyEvent
  13. Can&#39;t call commit when autocommit=true(转)
  14. java集合系列——java集合概述(一)
  15. [BZOJ1207] [HNOI2004] 打鼹鼠 (dp)
  16. SQL求几何重心
  17. DD常用命令组合
  18. poj 1177 --- Picture(线段树+扫描线 求矩形并的周长)
  19. jquery筛选数组之grep、each、inArray、map的用法及遍历son对象(转)
  20. 3.python函数编程-reduce函数

热门文章

  1. 大马过安全狗拿webshell方法
  2. java设计模式解析(11) Chain责任链模式
  3. Dubbo源码分析(4):Protocol
  4. Django源码分析rest_framework 关于re_path(&#39;^publish/&#39;, views.PublishView.as_view()总结
  5. 织梦DedeCMS会员空间内的文章列表无法分页的解决方法
  6. LightOJ-1275-Internet Service Providers(数学)
  7. 3、HDFS架构和YARN架构
  8. Python中对列表排序实例
  9. grep命令选项
  10. (3)Go运算符