更新/更改存储在NSArray中的NSDictionary键的值

ros*_*ump 1 objective-c nsdictionary nsarray nspredicate segue

我有一个NSArray包含NSDictionary客户数据.我使用的NSPredicate过滤array,并使之通过ViewControllerssegues.我正处于一个阶段,我想改变存储在其中的键的一些值dictionary.这怎么可以实现?

我的prepareForSegue方法

if ([[segue identifier] isEqualToString:@"showClients"]) {
            // Detect selected row
            NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
            // Extract value from the Clinic_Location attribute
            NSString *cString = [[_clinicList valueForKey:@"Clinic_Location"] objectAtIndex:indexPath.row];
            NSLog(@"Row pressed: %@", cString);

            // Set predicate where Clinic_Location equals the clinic string extracted from the selected row
            NSPredicate *predicate = [NSPredicate predicateWithFormat:@"Clinic_Location == %@", cString];
            // Filter the client array using this predicate
            filteredClientArray = [dataStart filteredArrayUsingPredicate:predicate];
            NSLog(@"Filtered array: %@", filteredClientArray);
            // Reload the table
            [self.tableView reloadData];

            // Sort the array by Appt_Time in ascending order
            NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]initWithKey:@"Appt_Time" ascending:YES];
            NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];
            NSArray *sortedArray = [filteredClientArray sortedArrayUsingDescriptors:sortDescriptors];
            filteredClientArray = [NSMutableArray arrayWithArray:sortedArray];

            // Pass the newly filtered & sorted array to next view
            PCClientsViewController *pcClients = segue.destinationViewController;
            pcClients.clientArray = filteredClientArray;
        }
Run Code Online (Sandbox Code Playgroud)

array现在只包含某些dictionaries在此基础上predicate(即当用户在选择一排TableView,让我们说'Manchester',那么只有dictionaries一个Clinic_LocationManchester得到传递给下一个视图.

prepareForSegue在下一个方法上的方法TableView类似于前一个方法,在这种情况下,我在所选行上使用匹配的姓氏predicate过滤dictionary并将其推送到下一个视图.现在我留下了如下array构造:

Filtered array: (
        {
        "Appointment_Attended" = Yes;
        "Appt_Time" = "2:00";
        "Client_Address_Line_1" = "Ap #452-4253 Massa. Street";
        "Client_Address_Line_2" = Montebello;
        "Client_Address_Line_3" = Hull;
        "Client_Address_Line_4" = Quebec;
        "Client_Address_Line_5" = Micronesia;
        "Client_Forename" = Veronica;
        "Client_Postcode" = 69591;
        "Client_Surname" = Ellis;
        "Client_Tel" = "(019376) 26081";
        "Clinic_Location" = Manchester;
        "Passed_To_Medical" = No;
        "Passed_To_Sol" = No;
    }
)
Run Code Online (Sandbox Code Playgroud)

我已尝试过许多不同的方法来更新特定的内容dictionary keys,array例如使用predicates,但似乎没有任何效果.例如:

NSPredicate* predicate = [NSPredicate predicateWithFormat:@"Client_Address_Line_1 == %@", [[_clientDetails valueForKey:@"Client_Address_Line_1"]objectAtIndex:0]];
NSLog(@"%@", predicate);
NSArray* filteredArray= [_clientDetails filteredArrayUsingPredicate: predicate];
[filteredArray performSelector: @selector(setValue:forKey:) withObject:self.clientAddLine1.text withObject:@"Client_Address_Line_1"];
Run Code Online (Sandbox Code Playgroud)

无论我尝试什么,我都会不断收到错误消息,例如:

***由于未捕获的异常'NSUnknownKeyException'终止应用程序,原因:'[<__ NSCFString 0x7904f590> setValue:forUndefinedKey:]:此类与密钥Client_Address_Line_1不符合密钥值编码.

***由于未捕获的异常'NSInvalidArgumentException'终止应用程序,原因:' - [__ NSDictionaryI setObject:forKey:]:无法识别的选择器发送到实例0x78774c70'

***由于未捕获的异常'NSUnknownKeyException'终止应用程序,原因:'[<__ NSDictionaryI 0x7bff6eb0> setValue:forUndefinedKey:]:此类与密钥Client_Address_Line_1不符合密钥值编码.

似乎无论我做什么我都无法改变或更新任何dictionary keys内部array.经过几个小时的研究,我开始怀疑这是否可能?我完全看错了吗?有一个更好的方法吗?后keys已经改变,我需要将它们保存回array,并将它传递回过ViewControllers也(可能Unwind Segues?)任何帮助深表感谢.

Gra*_*yer 10

您只能更改NSDictionary的可变子类中键的值,NSDictionary本身是不可变的.

所以既然你已经改成了一个可变数组,你也可以为每个字典做同样的事情:

filteredClientArray = [NSMutableArray arrayWithArray:sortedArray];
for(NSDictionary *d in [filteredClientArray copy])
{
    NSMutableDictionary * m = [d mutableCopy];
    [filteredClientArray replaceObjectAtIndex:[filteredClientArray indexOfObject:d] withObject:m];
}
Run Code Online (Sandbox Code Playgroud)