MayurCM
MayurCM

Reputation: 701

Terminating app due to uncaught exception 'NSUnknownKeyException' this class is not key value coding-compliant for the key .img

Trying to load image asynchronously I'm getting this error "Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ valueForUndefinedKey:]: this class is not key value coding-compliant for the key img.'" My code is as below

 NSString *str = "URL of an image";

    NSMutableDictionary *record = [NSMutableDictionary dictionary];
    [record setObject:str forKey:@"img"];

    record = [_array objectAtIndex:indexPath.row];



   dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,  0ul);
    if ([record valueForKey:@"img"]) {
        NSLog(@"in if");
        cell.m_img.image =  [record valueForKey:@"img"];
    } else {
        dispatch_async(queue, ^{
             NSLog(@"in else");
            NSURL  *imageurl = [[NSURL alloc] initWithString:str];
            NSData *image = [[NSData alloc] initWithContentsOfURL:imageurl];

            dispatch_async(dispatch_get_main_queue(), ^{
                [record setValue:[UIImage imageWithData:image] forKey:@"img"];

                [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
            });
        });
    }

Please advise where am I getting wrong here. Thanks Mayur

Upvotes: 0

Views: 1252

Answers (4)

MayurCM
MayurCM

Reputation: 701

Solved The problem with the help of your comments and answer. What I did is created NSMutable Dictionary in Globally used class and initialised the variable. Thanks all for the help

arr = [[NSMutableDictionary alloc] init];


dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,  0ul);
    if ([[[DataManager sharedInstance] arr] objectForKey:str]) {
        NSLog(@"in if");

         [cell m_img].image = [UIImage imageWithData:[[[DataManager sharedInstance] arr] objectForKey:str]]; 
    } else {
        dispatch_async(queue, ^{
             NSLog(@"in else");



                NSURL  *imageurl = [[NSURL alloc] initWithString:str];
                NSData *image = [[NSData alloc] initWithContentsOfURL:imageurl];
                [[[DataManager sharedInstance] arr] setObject :image forKey:str];
                [cell m_img].image = [UIImage imageWithData:[[[DataManager sharedInstance] arr] objectForKey:str]]; 

        });
    }

Upvotes: 0

Hermann Klecker
Hermann Klecker

Reputation: 14068

It is ost likeli this line

[record valueForKey:@"img"]

objectForKey: will return nil in the event that the key img is not set. The better choice in your case.

However, please review your code in general. You start off by creating a new NSMutableDictionary and assign it to record. Then you add a string object to that dictionary. Fine so far. After that you fetch an object from the array _array which you assign to record too. By then you do not have any reference to the newly created dicitionary any more. Is that intended. If you do not ARC then you create a memory leak here.

Edit in response to a comment below:

NSMutableDictionary *record = [NSMutableDictionary dictionary]; // here you create a new empty instance of NSMutableDictionary and store it in record. It has a retain count of 1
[record setObject:str forKey:@"img"]; // here you add an object to that new dictionary. Now it has exactly one entry with the key "img"
record = [_array objectAtIndex:indexPath.row]; //and here you discard the retained newly creaded dictionary by assigning another one from the array _array. What is the purpose of that?

Upvotes: 0

Divyu
Divyu

Reputation: 1313

 Check if object in array is of dictionary type

  NSString *str = "URL of an image";

    NSMutableDictionary *record = [NSMutableDictionary dictionary];

if([[_array objectAtIndex:indexPath.row]isKindOfClass:[NSDictionary class]])
    record = [_array objectAtIndex:indexPath.row];
else
      [record setObject:str forKey:@"img"];


   dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,  0ul);
    if ([record valueForKey:@"img"]) {
        NSLog(@"in if");
        cell.m_img.image =  [record valueForKey:@"img"];
    } else {
        dispatch_async(queue, ^{
             NSLog(@"in else");
            NSURL  *imageurl = [[NSURL alloc] initWithString:str];
            NSData *image = [[NSData alloc] initWithContentsOfURL:imageurl];

            dispatch_async(dispatch_get_main_queue(), ^{
                [record setValue:[UIImage imageWithData:image] forKey:@"img"];

                [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
            });
        });
    }

Upvotes: 1

Adithya
Adithya

Reputation: 4705

Replace

[record valueForKey:@"img"]

with

[record objectForKey:@"img"]

Upvotes: 1

Related Questions