在强类型集合中为空?

时间:2017-06-02 21:57:13

标签: ios objective-c cocoa-touch build warnings

我有一个强类型的集合:

NSMutableArray<SupportClass *> *_items;

我需要在其中添加一个null之类的对象。当您需要在ObjC中使用非类型集合时 - 使用[NSNull null]对象:

[_items replaceObjectAtIndex:index withObject:[NSNull null]];

但是对于键入的那个,我在该行上收到以下警告:

  

不兼容的指针类型将'NSNull * _Nonnull'发送到参数   输入'SupportClass * _Nonnull'

我理解 为什么 此示例中出现警告,其中混合了类型集合和[NSNull null]对象。

使用complile时间类型检查获得强类型集合的正确方法是什么,同时能够将null个类似对象放入其中?

1 个答案:

答案 0 :(得分:1)

  

我有一个强类型的集合:

NSMutableArray<SupportClass *> *_items;

结合你的两条评论:

  

但是我知道的[大多数]编程语言允许使用带有编译时类型检查的类型集合,同时能够将null对象放入其中。所以我只想找到一种方法来对ObjC做同样的事情。

您面临的问题是因为您正在使用最近添加的Objective-C,旨在改善与Swift的交互操作,而Swift不允许您以这种方式将空值混合到“强类型集合”中。

Swift模型通常用“非null引用和可选”模型替换您习惯使用的“引用或null”模型。在Swift中,对SomeClassType的引用为非null,而SomeClassType?类型是Optional<SomeClassType>的简写。 Optional类型有两种情况:.none.some(v),Swift允许您通过与.none进行比较来测试nil

Swift没有发明这个模型(像语言的大多数部分一样),它是从其他部分继承而来的,就像许多函数式语言一样,它们是这些标记的联合体的强大用户

  

我的问题是:从经验丰富的ObjC开发人员的角度来看,哪一个是首选的?

正如您尝试的那样使用NSNull。这是Apple推荐的方式,NSNull raison d'être,但可以追溯到Apple引入轻量级泛型以帮助Obj-C之间的桥梁和斯威夫特。

如何在后轻量级泛型世界中使用“引用或null”模型?我认为你知道大多数替代方案,包括:

  • 别。要么不使用Obj-C中的强类型集合,要么在Swift模型之后使用它们。
  • 使用Swift。如果您想要在运行时键入静态强类型,请使用基于它的语言。
  • 使用子类。覆盖每个方法/属性以抛出非法使用null异常。添加isNull谓词。等
  • 使用尊贵的对象。不喜欢继承,那么只需创建一个类的唯一实例作为null case。添加适当的方法/属性以支持它。
  • 在Obj-C中构建您自己的Optional
  • 突破纸墙。轻量级泛型对于标准集合来说确实是纸上薄层,如果必须,只需break through it

没有一种“正确的方法”可以解决您的问题。看看你的设计,决定“零参考”模型是否关键,选择适合你情况的解决方案。

HTH