【问题标题】:Pass NSObject (conditional data) to TableView将 NSObject(条件数据)传递给 TableView
【发布时间】:2015-01-20 19:32:26
【问题描述】:

首先,对不起,如果标题令人困惑,我不知道该怎么说。我将简要解释一下我的应用。

用户会看到一个登录屏幕(非常基本,没有服务器端的东西),他们可以在其中按特定顺序登录三个不同的公司(Company A, Company B, and Company C)。一旦用户成功登录到Company A,他们就会看到TableViewLoginViewController(普通ViewController)从Dropbox下载ListOfClinics.xml文件并使用NSXMLParser解析它,并将对象传递给ClinicsViewController以显示诊所位置列表。

ListOFClinics.xml 示例:

<Clinic>
    <Location>
        <Clinic_Location>Manchester</Clinic_Location>
    </Location>
    <Location>
        <Clinic_Location>Liverpool</Clinic_Location>
    </Location>
    <Location>
        <Clinic_Location>Birmingham</Clinic_Location>
    </Location>
    <Location>
        <Clinic_Location>London</Clinic_Location>
    </Location>
    <Location>
        <Clinic_Location>Leeds</Clinic_Location>
    </Location>
</Clinic>

ClinicViewControllerTableViewController。在填充表格时,应用程序会从 Dropbox (Clients.xml) 下载另一个文件并对其进行解析以供使用。这个想法是用户可以点击包含位置的TableView cell,例如曼彻斯特,来自Clients.xml的新解析数据应该传递到下一个视图(ClientsViewController)并显示所有注册到曼彻斯特诊所。

Clients.xml 示例:

<Client>
    <Clinic_Location>Manchester</Clinic_Location>
    <Client_Forename>Frank</Client_Forename>
    <Client_Surname>Wade</Client_Surname>
    <Client_Address_Line_1>Law Lane</Client_Address_Line_1>
    <Client_Address_Line_2>Money House</Client_Address_Line_2>
    <Client_Address_Line_3>Didsbury</Client_Address_Line_3>
    <Client_Address_Line_4>Manchester</Client_Address_Line_4>
    <Client_Address_Line_5></Client_Address_Line_5>
    <Client_Postcode>M20 2WS</Client_Postcode>
    <Client_Tel>01615559090</Client_Tel>
    <Appt_Time>15:30</Appt_Time>
    <Appointment_Attended>Booked</Appointment_Attended>
    <Passed_To_Medical>Complete Pass</Passed_To_Medical>
    <Passed_To_Sol>no</Passed_To_Sol>
</Client>
<Client>
    ...
</Client>

如您所见,两个 .xml 文件都有 Clinic_Location 元素。我不太担心错误检查以确保这些数据匹配(.xml 文件是通过另一个系统导出的,因此两者应该具有相同的位置)。我需要实现的是,当有人点击曼彻斯特时,下一个TableView 会显示在曼彻斯特诊所注册的客户列表。

更新

我创建了一个新的NSObject 类,在ClientData.h 中声明所有属性并在ClientData.m 中综合它们。

ClientData.h
@interface ClientData : NSObject

@property (strong) NSString *clinicLocation;
@property (strong) NSString *foreName;
...

ClientData.m
@implementation ClientData

@synthesize clinicLocation;
@synthesize foreName;
...

下面是我的解析器组件的sn-p,使用KVC来存储解析后的数据。

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {

    if ([elementName isEqualToString:@"Client"]) {
        // save to data structure object with KVC
        ClientData *clientData = [[ClientData alloc]init];
        clientData.clinicLocation = clinicLocation
        clientData.foreName = foreName;
        ...

        // count number of clients
        clientCount++;
        [client setObject:clinicLocation forKey:@"Clinic_Location"];
        [client setObject:foreName forKey:@"Client_Forename"];
        ...
        [dataStart addObject:[client copy]];
    }
}

如果我用NSLog(@"Forename: %@", clientData.foreName);等记录NSObject字符串,输出是正确的。

我正在使用带有 segues 的情节提要来推动下一个视图。我应该实现prepareForSegue 来传递NSObject (ClientData) 还是tableView didSelectRowAtIndexPath?这是我尝试过的:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
        if ([[segue identifier] isEqualToString:@"showClients"]) {

            // clientData is declared on the destinationViewController
            PCClientsViewController *pcClients = segue.destinationViewController;
            pcClients.clientData = [[ClientData alloc]init];
            pcClients.clientData.foreName = foreName;
        }
}

这可行,尽管只有一个 foreName 值被传递到下一个 TableView。我的NSObject 类是否每次我分配一些东西时只存储一个值?换句话说,如果我解析具有 100 个 foreName 属性的 100 条记录,是所有 100 个值都保留还是只保留最后一个?

我仍然不知道在这里做什么测试,只将相关数据传递到下一个视图(即,如果用户点击Manchester,则将所有具有Clinic_LocationManchester 的客户端传递到下一个视图)。我是否应该创建一个新的NSObject 类来存储ListOfClinics.xml 数据并针对我的ClientData NSObject 中的CLinic_Location 值对其进行测试?

【问题讨论】:

    标签: ios objective-c nsxmlparser nsobject key-value-coding


    【解决方案1】:

    创建一个简单的数据结构对象并传递它。

    @interface ClientData
    @property (strong) NSString *foreName;
    @property (strong) NSString *surName;
    // etc.
    @end
    
    @interface TargetViewController
    @property (strong) ClientData *clientData;
    @end
    

    【讨论】:

    • 感谢您的回复。请查看我更新的帖子:我已经实施了您的解决方案,但我正在努力将相关数据仅传递到下一个视图(请参阅最后一段)。
    • 您应该使用clientData.clinicLocation = clinicLocation[clientData setClinicLocation:clinicLocation] 而不是[clientData setValue:clinicLocation forKey:@"clinicLocation"]。当您使用 @property 时,这些方法已经为您创建好了。
    • 好的,谢谢,知道这很方便!我已经用你的代码更新了我的问题。这似乎运作良好,现在我可以传递一些数据,例如foreName,尽管只有最后解析的foreName 值被传递。我的 NSObject 类中的值每次都会被覆盖吗?我有 100 多个客户记录,例如,如果曼彻斯特有 10 个 Clinic_Location 标签,当我点击曼彻斯特时,我应该看到这 10 个客户和所有详细信息(surName, address, postcode 等)。我是否以错误的方式处理了这个问题?我不想让 Core Data 复杂化...
    • 抱歉再发表评论,但我不能只传递解析数据时创建的NSMutableArray 吗?如果您在我的问题中查看我的 parser didEndElement 方法,则数组 datastart 包含所有客户端数据。我已经做了一个快速测试,我可以用pcClients.clientArray = dataStart; 将它传递给下一个TableView,并用cell.textLabel.text = [[_clientArray objectAtIndex:indexPath.row]objectForKey:@"Client_Forename"]; 显示所有客户端的名字。我能不能在此之前不做测试,只在前一个 TableView 单元格上显示与 Clinic_Location 相关的每个客户端?
    • 你可以通过任何你喜欢的。我个人建议坚持使用代表您正在做的事情的数据对象,而不是使用字典和数组。它更简洁,输入的字符更少,并允许您的 IDE 为您自动完成属性。如果您要传递多个客户端,请构造一组客户端,但我仍然推荐客户端对象。
    【解决方案2】:

    prepareForSegue 中,pcClients 的属性clientDatanil,如果你给它的属性名赋任何值,它不会被保存,因为它没有分配内存来保存它。 您可以这样做来解决您的问题:

    pcClients.clientData = [ClientData alloc] init];
    pcClients.clientData.foreName = foreName;
    

    【讨论】:

    • 感谢您的回复。我已经用您实施的解决方案更新了我的问题,但是在将数据传递到下一个视图时,NSLog 仍然显示(null)
    • NSLog 仍然显示 (null),因为您在分配之前打印了该值。
    猜你喜欢
    • 1970-01-01
    • 2011-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-13
    • 1970-01-01
    • 1970-01-01
    • 2021-06-10
    相关资源
    最近更新 更多