Error when trying to get value of an entity attribute

| | August 4, 2015

I’m trying to get value from entity attribute:

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.mapaView setDelegate:self];

    MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init];
    request.naturalLanguageQuery = self.loja.endereco; // <-- Here
    request.region = self.mapaView.region;

    MKLocalSearch *search = [[MKLocalSearch alloc] initWithRequest:request];

    [search startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error)
        NSMutableArray *placemarks = [NSMutableArray array];
        for (MKMapItem *item in response.mapItems) {
            [placemarks addObject:item.placemark];
        [self.mapaView removeAnnotations:[self.mapaView annotations]];
        [self.mapaView showAnnotations:placemarks animated:NO];

But I get this error:

2015-08-03 21:01:41.196 MinhaBrasilia[2465:69970] -[__NSCFDictionary endereco]: unrecognized selector sent to instance 0x7fb2faed1910
2015-08-03 21:01:41.199 MinhaBrasilia[2465:69970] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary endereco]: unrecognized selector sent to instance 0x7fb2faed1910'

Loja (self.loja) is an entity, which was created from a plist, filtered using NSPredicate, loaded by method tableView:cellForRowAtIndexPath and passed as parameter via prepareForSegue:sender, all in the previous screen.

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
     LojaTableViewCell *celula = [tableView dequeueReusableCellWithIdentifier:IdentificadorCelula

     self.listaFiltrada = [self carregarPlistDeLojasComId:identificadorBtn filtradaPor:self.txtCategoria];

     self.loja = [NSEntityDescription insertNewObjectForEntityForName:@"Loja" inManagedObjectContext:self.managedObjectContext];

     [self.loja setValue:[[self.listaFiltrada objectAtIndex:indexPath.row] objectForKey:@"titulo"] forKey:@"titulo"];
     [self.loja setValue:[[self.listaFiltrada objectAtIndex:indexPath.row] objectForKey:@"subtitulo"] forKey:@"subtitulo"];
     [self.loja setValue:nil forKey:@"categoria"]; //Not implemented
     [self.loja setValue:[[self.listaFiltrada objectAtIndex:indexPath.row] objectForKey:@"endereco"] forKey:@"endereco"];
     [self.loja setValue:nil forKey:@"quadra"]; //Not implemented
     [self.loja setValue:[[self.listaFiltrada objectAtIndex:indexPath.row]  objectForKey:@"telefone"] forKey:@"telefone"];

     [celula preencherCelulaComTitulo:self.loja.titulo

    [celula setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
     return celula;

- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    self.loja = [self.listaFiltrada objectAtIndex:indexPath.row];
    [self performSegueWithIdentifier:SegueLoja sender:self.loja];

#pragma mark - Segue
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if([segue.identifier isEqualToString:SegueLoja]) {
        DetalheViewController *detalheVC = (DetalheViewController *)[[segue destinationViewController] topViewController];
        [detalheVC setLoja:sender];

Apparently I’m getting a dictionary, in which, if I do request.naturalLanguageQuery = [self.loja valueForKey:@"endereco"]; I can get the attribute I want, but this way I believe that I am not using the resources of CoreData.

One Response to “Error when trying to get value of an entity attribute”

  1. The error you are getting is because self.loja is a dictionary: in didSelectRowAtIndexPath you have:

    self.loja = [self.listaFiltrada objectAtIndex:indexPath.row];

    which is an NSDictionary derived from your filtered plist, NOT the NSManagedObject that you create in cellForRowAtIndexPath. The dictionary does not implement the endereco method, hence the error. It does implement valueForKey, so that will work: but if you follow this route, you are accessing the key of a dictionary, not the NSManagedObject.

    I think you should rethink your approach – using cellForRowAtIndexPath to process the plist into NSManagedObjects is a bad idea. It will only be called for visible cells, and will potentially be called several times for the same row (if it is scrolled on and off screen). I would write a routine to process all the plist into Core Data, and produce an array of NSManagedObjects that you can then use as the data source for the table view.

Leave a Reply