我编写了一个大型的社交网络iPhone应用程序,遇到的最大问题之一是NSInteger(以及所有其他NS非对象类型)不是一等公民。这个问题源于它们显然没有表示nil值的方法。
这导致了两个主要问题:
- 在存储和从集合中检索数据时,需要花费大量的开销并且难以理解,因为需要将其转换为和从NSNumber。
- 无法表示空值。通常我想能够表示“未设置”的值。
解决方法之一是始终使用NSNumber,但这会变得极其混乱。在用户模型对象中,我将有大约20个不同的NSNumbers,并且没有简单的方法来告诉每个数字是浮点数,整数,布尔值等等。
因此,以下是我对潜在解决方案的思考以及它们的优缺点。 我并不是真的对它们中的任何一个都非常满意,因此我想征求反馈和/或此问题的替代解决方案。
- 继续使用NSInteger类型,只使用NSIntegerMax来表示nil。
PRO - 内存开销小
PRO - 类型清晰
CON - NSIntegerMax并不真正表示 nil。 如果程序员不小心或不知道这个约定,无效值可能会泄漏到显示层。
CON - 无法在集合中存储它们,需要进行转换。 - 使用NSNumber,并使用匈牙利命名法指定类型(例如NSNumber fHeight,NSNumber iAge)
PRO - 一等公民
PRO - 解决了nil问题
CON - 内存开销增加
CON - 失去编译器类型检查
CON - 匈牙利命名法存在争议 - 编写自己的一等原始对象类型(类似于Javahttp://developer.android.com/reference/java/lang/Integer.html)
PRO - 一等公民
PRO - 解决了nil问题
PRO - 保持编译器类型检查
PRO - 对象将比NSNumber更简单。 内部存储将特定于数据类型。
CON - 内存开销增加
CON - 牺牲了一定的代码可移植性和兼容性
寻找支持其中一种技术(或者如果你有其他的选择也行)的有力论据。
更新
我已经开始了一个开源项目 (Apache 2.0),我会在有时间的时候将我们内部的一些类放进去。目前它包括了一些常见本地数据类型 (BOOL、CGFloat、NSInteger、NSUInteger) 的对象包装器。我们之所以选择这样做,是因为它将这些数据类型升级为严格类型的一等公民。也许你不同意这种方法,但它对我们很有效,如果你愿意,可以随意使用它。
我正在添加其他我们发现有用的类,包括一个磁盘支持的LRU缓存、一个“Pair”对象、一个低内存释放池等等。
compare: withPrecision
吗? - Stephen Furlani