INTUGroupedArray 1.1.5

INTUGroupedArray 1.1.5

测试已测试
语言语言 Obj-CObjective C
许可 MIT
发布上次发布2017年6月

Kristina ThaiTyler FoxJason HallLucien Dupont维护。



  • Lucien Dupont

INTUGroupedArray

用于 iOS 和 OS X 的 Objective-C 和 Swift 集合,用于存储按部分分组的对象。

INTUGroupedArray 是 Objective-C 数据结构,它将常见的单维数组提升到下一个维度。分组数组具有熟悉的 API,可以很好地与 NSArray 等Foundation 集合一起使用,并提供全功能的不可变和可变变体。一个薄的桥梁将分组数组引入 Swift 作为原生类,在这里它利用泛型、可选、下标、字面量、元组等更多功能的力量、安全性和灵活性。

INTUGroupedArray 非常灵活,可以用作通用数据存储机制来替换复杂的嵌套数组或其他数据结构的组合。分组数组非常适合用作 UITableView 数据源,因为它高度兼容数据源和协议回调--在许多情况下只需要一行代码。然而,它适合在整个 iOS 和 OS X 应用程序的堆栈中使用。

设置

Objective-C

从 GitHub 手动

  1. Source/INTUGroupedArray 目录下载 Objective-C 源文件。
  2. 将所有文件添加到您的 Xcode 项目中(拖放最容易)。
  3. 导入伞头文件 INTUGroupedArrayImports.h,以便所有分组数组类都可以使用。

Swift

  1. 要在 Swift 中使用分组数组,您首先需要获取 Objective-C 源代码并将其集成到您的项目中(请参阅上面)。
  2. Source/Swift 目录下载 GroupedArray.swift Swift 源文件并将其添加到您的项目中。
  3. 如果您还没有设置,您需要为您的项目设置一个 Objective-C 桥接头
  4. 将伞头文件 INTUGroupedArrayImports.h 添加到您的桥接头文件中。(Swift 分组数组类依赖于此,这样才能访问 Objective-C 源。)

此时,原生 Swift 类 GroupedArrayMutableGroupedArray 将可用于项目中 Swift 代码中的使用。

概念

从高层次来看,分组数组是一组节,每个节都包含一个对象数组。节和对象可以是任何类的实例。

INTUGroupedArray Illustration

分组数组与UITableView的结构紧密对应,它也按照一或多个节组织行。因此,表格视图的数据源和代理方法直接映射到分组数组的API方法。

一些分组数组的API与字典的API相似(例如,通过传递节本身而不是其索引来检索节中的对象)。注意,与字典不同,分组数组不需要元素(节或对象)实现-hash方法,也不要求元素在分组数组内保持稳定的哈希值。然而,这会以某些操作(例如节查找)的性能为代价。

就如同Foundation集合一样,分组数组有两种形式

  • INTUGroupedArray:一个不可变的分组数组。线程安全。(Swift类型:GroupedArray
  • INTUMutableGroupedArray:一个可变的子类。非线程安全。(Swift类型:MutableGroupedArray

作为最佳实践,你应该优先选择静态不可变的分组数组而非动态可变的变体。

大多数操作的性能都在.M文件中每个方法实现的上方详细文档中进行了注释。(头文件中的文档被简略,以方便API参考。)

关键设计点

不得有空的节

分组数组中的每个节都必须至少包含一个对象,类似于字典中的每个键都必须与一个值相关联。这种设计简化了处理多维数据结构时的某些复杂性。例如,这允许在最后一个对象被删除后立即删除节。如果确实需要空节用例,可以使用单个占位对象来实现。

节应唯一

分组数组的设计假设分组数组中的两个节不被视为相等(使用-isEqual:)。例如,这允许在可变分组数组中根据需要自动创建和删除节。虽然不鼓励这么做,但技术上可以存在重复的节,但这会损害基于节API的功能(例如-indexOfSection:-indexOfObject:inSection:-addObject:toSection:等),这些API将只操作一个节实例。

错误被优雅处理

大多数错误不是致命错误,并且有比终止整个应用程序更好的恢复方式。在调试构建中,分组数组会在错误发生时抛出异常,但在发布构建中,由于禁用了断言,它不会崩溃。例如,尝试访问越界的节索引将在调试时抛出异常,但在发布时将简单地返回nil。在Swift分组数组中,这通过隐式未绑定可选来传达——这些值只有在发生错误时才会是nil,因此如果您想避免运行时错误,应该检查nil。

使用方法

以下是分组数组常见操作的几个片段。请注意,这仅仅是整个API的一部分——有关完整API和文档,请参阅源文件。

Objective-C

使用字面量语法创建不可变的分组数组

INTUGroupedArray *groupedArray = [INTUGroupedArray literal:@[@"Section 1", @[@"Object A", @"Object B"],
                                                             @"Section 2", @[@"Object C"],
                                                             @"Section 3", @[@"Object D", @"Object E", @"Object F"]]];

计算分组数组中部分和对象的数量

NSUInteger sectionCount = [groupedArray countAllSections];
NSUInteger objectCount = [groupedArray countAllObjects];

访问第一个部分

id section = [groupedArray sectionAtIndex:0];

获取第一个部分中的对象数组

NSArray *objectsInSection = [groupedArray objectsInSectionAtIndex:0];

使用NSIndexPath访问第一个部分中的第一个对象

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
id object = [groupedArray objectAtIndexPath:indexPath];	

获取所有对象的数组

NSArray *allObjects = [groupedArray allObjects];

遍历分组数组中的对象

for (id object in groupedArray) { /* do something with object */ }

获取不可变分组数组的一个可变副本

INTUMutableGroupedArray *mutableGroupedArray = [groupedArray mutableCopy];

将一个对象添加到第一个部分的末尾

[mutableGroupedArray addObject:@"New Object" toSectionAtIndex:0];

在第三部分的开头插入一个对象

[mutableGroupedArray insertObject:@"Another Object" atIndex:0 inSection:@"Section 3"];

删除第二个部分

[mutableGroupedArray removeSectionAtIndex:1];

测试两个分组数组是否相等(包含相同的部分和对象)

if ([groupedArray isEqual:mutableGroupedArray]) { /* the two grouped arrays are equal */ }

Swift

使用数组字面量语法创建不可变的分组数组(含部分和类型为NSString的对象)

let groupedArray: GroupedArray<NSString, NSString> = ["Section 1", ["Object A", "Object B"],
                                                      "Section 2", ["Object C"],
                                                      "Section 3", ["Object D", "Object E", "Object F"]]

计算部分和对象的数量

let sectionCount = groupedArray.countAllSections()
let objectCount = groupedArray.countAllObjects()

使用下标访问第一个部分

let section = groupedArray[0]

使用下标访问第二个部分中的第一个对象

let object = groupedArray[1, 0]

使用下标通过索引路径访问对象

let indexPath = NSIndexPath(forRow: 0, inSection: 0)
let object = groupedArray[indexPath]

如果有,获取分组数组中的最后一个对象

if let lastObject = groupedArray.lastObject() { /* do something with lastObject */ }

遍历分组数组

for (section, object) in groupedArray { /* do something with the section/object */ }

获取不可变分组数组的一个可变副本

var mutableGroupedArray = groupedArray.mutableCopy() // the type of mutableGroupedArray is inferred to be: MutableGroupedArray<NSString, NSString>

使用下标替换第三部分的第一个对象

mutableGroupedArray[2, 0] = "Another Object"

测试两个分组数组是否相等(包含相同的部分和对象)

if (groupedArray == mutableGroupedArray) { /* the two grouped arrays are equal */ }

示例项目

提供了两个示例项目。

Objective-C示例项目演示了如何使用分组数组在iOS上支持表格视图。此项目需要Xcode 6.0或更高版本。

Swift示例项目突出了使用Swift接口时的其他可用功能。此项目需要Xcode 6.1或更高版本。

单元测试

单元测试套件集成到Objective-C示例项目中。它是跨平台的,可以在iOS和OS X上运行。

问题 & 贡献

如果您有问题、建议或其他评论,请在此GitHub上打开一个问题

欢迎和鼓励发送拉取请求!虽然没有官方指导方针,但请尽量与现有的代码风格保持一致。任何贡献都应包括为维持全面的测试覆盖率而必需的新或更新的单元测试。

许可证

INTUGroupedArray遵循MIT许可证提供。

INTU在GitHub上

查看更多来自Intuit的iOS和OS X开源项目