从两个 NSArrays 中包含的数据准备一个 NSDictionary 用于 UITableView

Posted

技术标签:

【中文标题】从两个 NSArrays 中包含的数据准备一个 NSDictionary 用于 UITableView【英文标题】:Prepare an NSDictionary from the data contained in two NSArrays for use in UITableView 【发布时间】:2015-05-06 14:45:10 【问题描述】:

我已经通过 SO 和其他网站广泛搜索了答案...也许我遗漏了什么和/或不正确理解 NSDictionary 的键/值编码结构?

我正在以编程方式在自定义控制器类中准备 UITableViewController。我有两个 NSArrays,它们是通过使用 Core Data 持久化的数据的迭代过程以固定结构(我选择的)构建的。

问题:我想将两个NSArrays 组合成一个NSDictionary,这样我就可以在UITableView 中使用它,并在tableView:cellForRowAtIndexPath: 数据源方法中插入适当的数据使用NSIndexPath 引用。

这是我的视图控制器层次结构...

TVC --> 继承核心数据 MOC 并设置全局属性; TVC_List --> 运行 FRC 以填充一系列多态表视图控制器中的任何列表; TVC_Detail --> 为从这些列表之一中选择的NSManagedObject 准备详细视图以供审核/编辑; TVC_ContactDetail --> 为选定的“联系人”类型的NSManagedObject 显示详细视图以供查看/编辑; TVC_AddressMethod --> 从一个实体关系中获取数据,该实体关系对选定的NSManagedObject“联系人”具有强引用,目的是在自定义构建的表格视图中显示。

是的,我考虑过使用单独的 FRC。更大的应用程序通过结构化的控制器多态性和层次结构为每个其他 TVC 使用 FRC。

我曾尝试为这个特殊情况控制器使用独立的 FRC,但它似乎无法提供我选择的特殊情况数据准备所需的灵活性在这种情况下使用。我已经了解了很多关于 FRC 和表格视图及其优点和局限性的知识,但同样,也许我遗漏了什么?


要详细解释...

我有一个自定义的 NSManagedObject ("DD_AddressMethod") 传递给控制器​​。自定义 NSManagedObject 包含“联系人”的联系信息数据。

例如,它包括以下(核心数据模型)实体属性/关系:

@property (nonatomic, retain) NSString *data;
@property (nonatomic, retain) DD_Contact *contact;
@property (nonatomic, retain) DD_Type *type;
@property (nonatomic, retain) DD_TypeChild *typeChild;

注意:以“DD_”开头的三个是与其他自定义NSManagedObjects 的关系。

我能够按照以下屏幕截图以编程方式构建动态UITableView(适用于 ios 联系人“Daniel Higgins”)。我无法正确地将数据分配到正确的部分:行:。

注意:为清楚起见,提供此屏幕截图是为了详细说明表格视图结构,但请注意分配给标签的数据不正确。仅供参考。

为了继续我的详细描述,自定义NSManagedObject 被分配给一个强引用变量。

从中我得到两个动态构造的NSArrays...

Array No.1:节标题(从实体关系“类型”中提取):

Printing description of mutableArraySectionHeaders:
<__NSArrayM 0x7b65e610>(
Telephone,
Facsimile,
Email
)

这个动态构造的数组提供数据来设置我的numberOfSectionsInTableView:tableView:titleForHeaderInSection: 数据源方法的值。

Array No.2 : 每节的行数:

Printing description of mutableArrayRowNumbers:
<__NSArrayM 0x7b661ef0>(
2,
1,
1,
0
)

这个动态构造的数组提供数据来设置我的tableView:numberOfRowsInSection: 数据源方法的值。

重申问题:我想要实现的是将这两个动态构造的数组(或类似的数组)组合成一个动态构造的NSDictionary,可用于填充@987654348 中的单元格@数据源方法。

例如,创建一个字典以便我的tableView:cellForRowAtIndexPath 数据源方法中的这行代码能够正常工作的东西......

cellData = self.dictionaryOfTwoArrays[indexPath];

我了解NSDictionary 将由对构成。在此特定示例中,两个数组具有不同数量的元素,因此对于此特定示例,动态构造的字典将需要从 Array No.2 中删除 0。但是对于另一个联系人,例如没有“传真”联系人type,可能只有两对要插入到动态构造的字典中。

有关信息,请注意数据本身描述为:

Printing description of mutableArrayAddressMethods:
<__NSArrayM 0x7b65d010>(
<DD_AddressMethod: 0x7b6e2140> (entity: AddressMethod; id: 0x7b644280 <x-coredata://C17E9176-4105-488B-86DA-3A94638E7FAF/AddressMethod/p3> ; data: 
    data = "555-478-7672";
    contact = "0x7b73b7a0 <x-coredata://C17E9176-4105-488B-86DA-3A94638E7FAF/Contact/p1>";
    type = "0x7b6d62c0 <x-coredata://C17E9176-4105-488B-86DA-3A94638E7FAF/Type/p60>";
    typeChild = "0x7b6a7670 <x-coredata://C17E9176-4105-488B-86DA-3A94638E7FAF/TypeChild/p54>";
),
<DD_AddressMethod: 0x7b6d6530> (entity: AddressMethod; id: 0x7b6d3dc0 <x-coredata://C17E9176-4105-488B-86DA-3A94638E7FAF/AddressMethod/p4> ; data: 
    data = "(408) 555-5270";
    contact = "0x7b73b7a0 <x-coredata://C17E9176-4105-488B-86DA-3A94638E7FAF/Contact/p1>";
    type = "0x7b6d62c0 <x-coredata://C17E9176-4105-488B-86DA-3A94638E7FAF/Type/p60>";
    typeChild = "0x7b6436a0 <x-coredata://C17E9176-4105-488B-86DA-3A94638E7FAF/TypeChild/p23>";
),
<DD_AddressMethod: 0x7b63f260> (entity: AddressMethod; id: 0x7b6abc20 <x-coredata://C17E9176-4105-488B-86DA-3A94638E7FAF/AddressMethod/p1> ; data: 
    data = "(408) 555-3514";
    contact = "0x7b73b7a0 <x-coredata://C17E9176-4105-488B-86DA-3A94638E7FAF/Contact/p1>";
    type = "0x7b6b72d0 <x-coredata://C17E9176-4105-488B-86DA-3A94638E7FAF/Type/p108>";
    typeChild = "0x7b6a7670 <x-coredata://C17E9176-4105-488B-86DA-3A94638E7FAF/TypeChild/p54>";
),
<DD_AddressMethod: 0x7b64e890> (entity: AddressMethod; id: 0x7b6b4480 <x-coredata://C17E9176-4105-488B-86DA-3A94638E7FAF/AddressMethod/p2> ; data: 
    data = "d-higgins@mac.com";
    contact = "0x7b73b7a0 <x-coredata://C17E9176-4105-488B-86DA-3A94638E7FAF/Contact/p1>";
    type = "0x7b6dc6e0 <x-coredata://C17E9176-4105-488B-86DA-3A94638E7FAF/Type/p9>";
    typeChild = "0x7b6a7670 <x-coredata://C17E9176-4105-488B-86DA-3A94638E7FAF/TypeChild/p54>";
)
)

【问题讨论】:

标题是否正确但单元格的内容不正确?可以粘贴生成要显示的数据的代码吗? 我用来生成UITableViewCells 的代码不正确——它是让表视图加载数据的“东西”。这不是问题。问题是问题,即我如何从显示的两个NSArrays 中构造一个NSDictionary,以便可以在tableView:cellForRowAtIndexPath 数据源方法中使用它...例如addressMethod = self.dictionaryOfTwoArrays[indexpath];,其中然后使用addressMethod(正确)填充表格视图单元格中的UILabels。 您的数组有不同数量的元素,但字典需要设置成对的东西。是要忽略 0 行号项目还是应该有一个额外的部分名称? 好点@PhillipMills。我会更新问题。零将应用于此特定示例中缺少的其他部分标题。 您似乎正在尝试重新创建 NSFetchedResultsController 将免费提供的内容 - 您是否考虑过该选项? 【参考方案1】:

不太确定我的问题是否正确,但无论如何,也许只是尝试将所有这些模型组合成二维数组,例如您的助手(视图模型)类可能如下所示:

@interface Helper

@property (nonatomic, strong) NSArray *sections; // 2D array which contains arrays

@end

@implementation Helper

- (NSInteger)numberOfSections 
  return self.sections.count;


- (NSInteger)numberOfRowsInSection:(NSInteger)section 
  return [self.sections[section] count];


- (MVVMModel *)modelAtIndexPath:(NSIndexPath *)indexPath 
  return self.sections[indexPath.section][indexPath.row];


@end

之后:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
  id model = [self.helper modelAtIndexPath:indexPath];
  ...

【讨论】:

感谢您的回答@dktcup。我似乎无法理解你的建议。你能详细说明一下吗?【参考方案2】:

如果 FRC 是不可能的,那么这就是“蛮力攻击”,可以这么说,对于您所说的问题:

NSMutableDictionary *dictionaryOfTwoArrays = [NSMutableDictionary new];
NSInteger arrayIndex = 0;
for (NSInteger sectionIndex = 0; sectionIndex < [mutableArrayRowNumbers count]; sectionIndex++) 
    NSInteger rowCount = [mutableArrayRowNumbers[sectionIndex] integerValue];
    for (NSInteger rowIndex = 0; rowIndex < rowCount; rowIndex++) 
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:rowIndex inSection:sectionIndex];
        dictionaryOfTwoArrays[indexPath] = mutableArrayAddressMethods[arrayIndex];
        arrayIndex++;
    

NSLog(@"dictionaryOfTwoArrays is %@",dictionaryOfTwoArrays);

当底层的可变数组发生变化时,你显然需要修改或重建这个字典。另外,请注意,您的 Array No.1 与这些目的无关,尽管您仍然可以使用它来填充部分标题。

有些人在 cmets 中建议的另一个选项是数组数组。可以按照以下思路构建:

NSInteger arrayIndex = 0;
NSMutableArray *sections = [NSMutableArray new];
for (NSInteger sectionIndex = 0; sectionIndex < [mutableArrayRowNumbers count]; sectionIndex++) 
    NSInteger rowCount = [mutableArrayRowNumbers[sectionIndex] integerValue];
    NSMutableArray *sectionRows = [NSMutableArray new];
    for (NSInteger rowIndex = 0; rowIndex < rowCount; rowIndex++) 
        [sectionRows addObject:mutableArrayAddressMethods[arrayIndex]];
        arrayIndex++;
    
    [sections addObject:sectionRows];

NSLog(@"Array of arrays is %@",sections);

然后,您必须使用以下内容解压缩数据:

NSArray *rowArray = sections[indexPath.section];
addressMethod = rowArray[indexPath.row];

【讨论】:

以上是关于从两个 NSArrays 中包含的数据准备一个 NSDictionary 用于 UITableView的主要内容,如果未能解决你的问题,请参考以下文章

从类中包含的结构访问变量

是否有一个 Excel 函数或脚本来查找和替换两个不同工作表中匹配的字段,并将其替换为第二个工作表中包含的另一个数据?

C - 当我尝试将结构从数组复制到结构中包含的数组时出现问题

C#:如何在 SplitContainer 面板中包含的 PictureBox 中添加两个滚动条

如何获取标签栏控制器中包含的所有视图控制器? iphone开发

ARM NEON:从 NEON 寄存器(Q/D 寄存器)中包含的地址加载数据