我们应该写`[NSMutableArray <nsstring * =“”> array]`?

时间:2016-01-08 12:20:45

标签: objective-c generics nsarray xcode7

Xcode 7引入了泛型。它允许提示,如:

允许警告,例如:

但它失败了许多事情,没有任何警告:

NSMutableArray<NSNumber *> *array;
array = [NSMutableArray<NSNumber *> arrayWithObjects:@0, @"", nil];
NSLog(@"%@", [array[1] class]);// __NSCFConstantString
array = [NSMutableArray<NSNumber *> arrayWithContentsOfURL:[NSURL URLWithString:@"http://ios.eezytutorials.com/sample-files/sample-array-plist.plist"]];
NSLog(@"%@", [array[0] class]); // __NSCFString

因此输入通用创建有点不可靠。

问题:我们应该使用不可靠的语法吗?

NSMutableArray<NSString *> *array;
array = [NSMutableArray<NSString *> array];
array = [NSMutableArray<NSString *> arrayWithArray:array];
array = [NSMutableArray<NSString *> arrayWithObjects:@"", @"", nil];
array = [NSMutableArray<NSString *> arrayWithContentsOfURL:url];

或简化语法?

NSMutableArray<NSString *> *array;
array = [NSMutableArray array];
array = [NSMutableArray arrayWithArray:array];
array = [NSMutableArray arrayWithObjects:@"", @"", nil];
array = [NSMutableArray arrayWithContentsOfURL:url];

我还担心显然无法对arrayWithContentsOfURLarrayWithContentsOfFile的返回值进行任何编译时保证。那些泛型对那些人来说总是无用的吗?

3 个答案:

答案 0 :(得分:4)

是的,应该使用泛型为编译器和开发人员提供进一步的类型规范信息。

在声明中提供数组将包含的对象类型至少是文档获取和错误检查是另一个好处。

还希望在将来的编译器版本中改进类型检查。

但是一般来说阵列中的混合类型不是一个问题,这样的错误往往会让开发人员感到困惑。如果我有一个Motorcycle个对象数组并添加一个Juggler对象,我可能会遇到一个主要的设计不匹配错误或重大错误。

最好的防御是良好的类和变量命名,而不是array,而是motorcycleListjugglerList。然后,如果我有motorcycleList addObject:juggler,很快就会发现在写入语句时出现错误。

对ObjC语言的这一补充只是明确规范发展的一个步骤:

id x = [NSMutableArray new];
NSMutableArray *list = [NSMutableArray new];
NSArray<NSString *> *stringList = [NSMutableArray new];

答案 1 :(得分:1)

你是对的,Obj-C中的泛型不完美,但是:

  • 某些类型检查优于无
  • 使代码更具自我记录性
  • Xcode的未来版本可以改进类型推断
  • 它已经平滑了与Swift的集成 - 随着时间的推移它将变得更加重要

缺点:

  • 没有发现100%的错误 - 但是做了什么?
  • 为您的代码添加一些额外的内容

总结:现在略有改进,但使您的代码更具有前瞻性。

答案 2 :(得分:0)

因为它确实触发了问题中描述的警告,所以使用具有指定泛型类型([NSMutableArray<NSString *> ...];)的构造函数是一种更好的方法。

但我们可以假设Objective-C中的泛型是为了过渡到Swift而引入的,在这方面,直接使用Swift更好