2010-04-09 34 views
0

如果之前已询问过此问题,但无法找到所需的信息,我表示歉意。目标C对象功能和传递阵列

基本上我想要使用来自服务器的信息填充UITableView,类似于SeismicXML示例。我将解析器作为单独的对象,是否正确分配,初始化该解析器的一个实例&,然后告诉RootViewController将它的表数据源作为解析器数组的副本。

我不能包含代码,因为我还没有写任何东西,我只是试图在我开始之前就开始设计。也许是这样的:

xmlParser = [[XMLParser alloc] init]; 

[xmlParser getXMLData]; 

// Assuming xmlParser stores results in an array called returnedArray 

self.tableDataSource = xmlParser.returnedArray 

这是做这件事的最好方法吗?

回答

3

不,你不想这样做。你不希望你的视图控制器直接访问数据模型的数组。这将在技术层面上起作用,但是它会很脆弱,并且可能会随着项目规模的扩大而失败。随着项目日益复杂化,您将希望越来越多地将数据模型对象(本例中为xmlParser)包装在方法的保护层中,以控制和验证数据模型如何更改。最终,您将拥有包含多个视图的项目,多个视图控制器以及来自用户和URL的信息。您需要养成使用数据模型对象的习惯,而不仅仅是一个愚蠢的商店,而是作为一个活跃的管理者和数据验证者。

在像这样的情况我也有我的数据模型的排列完全使其成为@protected或@private财产包裹。然后我会有专门的方法来获取或插入数据到数据模型类本身的实际数组中。数据模型之外的任何对象都不应该直接访问数组或者不知道其索引。

因此,在这种情况下,您的数据模型将有类似:

- (NSString *) textForLineAtIndexPath:(NSIndexPath *) anIndexPath{ 
    //... do bounds checking for the index 
    NSString *returnString=[self.privateArray objectAtIndex:anIndexPath.row]; 
    if (returnString=='sometest'){ 
     return returnString; 
    } 
    return @""; //return an empty string so the reciever won't nil out and crash 
} 

以及用于设置行,如果你需要一个setTextForLineAtPath:方法。

一般的教学材料没有花足够的(通常是没有)的时间谈论的数据模型,但数据模型实际上是方案的核心。这是应用程序的实际逻辑所在,因此它应该是项目中最复杂和经过全面测试的类之一。

一个好的数据模型应该接口不可知即它应着眼基于接口,基于web界面或甚至在命令行工作。它不应该知道也不在乎它的数据将显示在tableview或其他任何界面元素或类型中。

当我开始一个新项目,我做的第一件事是注释掉“[窗口makeKeyAndVisible]。”在应用程序的代表。然后,我创建我的数据模型类,并通过加载数据并记录输出来测试它的老派。只有当它按我希望的方式工作时,我才能进入用户界面。

因此,真正想想应该在抽象层面上做什么。在自定义类中对该逻辑进行编码。隔离来自任何其他对象的所有直接操作的数据。在提交之前验证数据的所有输入。

这听起来像很多工作,它是。对于一个小项目而言,这感觉就像是矫枉过正,而且在很多情况下是这样。但是,随着应用程序复杂度的增加,尽早获得这种习惯将会很快带来巨大的收益。

+0

+1我完全同意,文档在解释一个考虑良好的模型层的绝对必要性方面很差。大多数示例只是将数据放入NSString或NSArray中,学生们被误导为复制这些内容。学生不会被教导这些例子过度简化了模型层,因为他们专注于其他部分。 – 2010-04-09 15:01:18

0

我是一名Mac程序员,而不是iPhone程序员;但在Mac上, self.tableDataSource = xmlParser.returnedArray不正确。您应该将表格的内容绑定到数组控制器(如果iPhone有一个?)或将数据源插座设置为RootViewController。

在你rootview控制器,您将实现方法:

– tableView:cellForRowAtIndexPath: 
– tableView:numberOfRowsInSection: 

对于– tableView:cellForRowAtIndexPath:你会返回一个UITableViewCell与您解析根据像这样的索引路径从XML接收到的数据:

UITableCell *myCell = [UITableCell new]; 
myCell.textLabel.text = [parsedXMLArray objectAtIndex:[indexPath indexAtPosition:indexPath.length-1]]; 
return myCell; 

)有些人不知道的是,你可以在所有自动调用alloc/init的NSObject子类上使用+ new类方法

对于– tableView:numberOfRowsInSection只返回数据数组的计数:

return parsedXMLArray.count; 
+0

iPhone不支持绑定,也没有收集控制器。你对Cocoa的建议是合理的,但在这里并不适用。 – TechZen 2010-04-09 14:25:14

0

不太。您希望数据源是实现UITableViewDataSource协议的对象;在这种情况下我会做的是创建一个对象,该对象实现该协议,并解析XML ,以便您可以将该数据源设置为该对象,并根据需要更新该表视图。因此,基于把你的代码(假设你的表视图的控制器内运行):

XMLParserAndDataSource xpads = [[XMLParserAndDataSource alloc] init]; 
[xpads getXMLData]; 
self.tableView.dataSource = xpads;

这可能是一个好主意,让这一类本身的NSXMLParser对象的引用,所以你可以用它来解析XML,然后提供便利方法(如getXMLData)以及供您自己使用的UITableViewDataSource方法。 (如果你走这条路线,你也应该让你的XMLParserAndDataSource类实现更有用的NSXMLParser委托方法,并酌情使用它们来更新你的表视图。)

0

不能编辑我的问题也不回复,只能发表我的回复作为答复。

@TechZen:我是人谁试图形成类比,让我了解。你的意思是这样的:我最初的想法就像进入档案室&在我的办公桌上倾倒所有的原件,在你建议的地方工作,更像是一个有组织的文件员,他将搜索数据我只能返回我需要的特定数据,而只能直接访问这些数据。 我理解正确吗?

@Tim:如果我以后需要解析器来获取数据的东西,这是不是一个表?这就是为什么我想将它转储到数组中,让调用者决定如何处理数据。你会建议第二个对象以新的形式提供数据吗? (我是否在这里或正确的轨道?

+0

是的,非常好的比喻。我打算偷走它非常好。 ;-)这正是它的样子。你走到柜台前,从店员那里索要一份文件,然后消失回到堆栈的黑暗凹槽中,然后随文件一起返回。你永远不会看到文件是如何组织的,他做了什么来检索文件。 – TechZen 2010-04-10 18:19:30

+0

很酷,谢谢。 – Patrick 2010-04-12 08:17:34