Reputation: 3834
So I pulled some JSON
data from a web service which is stored in an NSArray
called _infoFromJSON
. Each array element in _infoFromJSON
essentially has a dictionary of key/value pairs. The goal is to add them to myVehicleObject
which is an NSMutableArray
for (NSDictionary* myDictionary in _infoFromJSON) {
myVehicleObject *vehicleInMembersProfile;
vehicleInMembersProfile = [[myVehicleObject alloc] init];
vehicleInMembersProfile.make = [[_infoFromJSON objectAtIndex:carCount] objectForKey:@"make"];
vehicleInMembersProfile.carName = [[_infoFromJSON objectAtIndex:carCount] objectForKey:@"nickname"];
vehicleInMembersProfile.year = [[_infoFromJSON objectAtIndex:carCount] objectForKey:@"year"];
carCount ++;
[self.myVehicleObject addObject:vehicleInMembersProfile] ;
};
With the above code I sort of achieved it, however it keeps adding the same 1st dictionary to myVehicleObject
, so it inserts the same NSDictionary
4 times In the past I have used this:
[self.myVehicleObject addObject:[vehicleInMembersProfile copy]] ;
When I do it it throws the following exception:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[myVehicleObject copyWithZone:]: unrecognized selector sent to instance 0xab4e130'
What am I doing wrong here? Thanks!
Update Requested Sample JSON:
{
color = SILVER;
engine = "";
id = "CF270B81-3821-4585-8C90-7089D7A8654E";
imageUrl = "https://www.someprotectedurl.com/somefile.png";
licensePlate = "ABC-123";
make = Honda;
model = "CR-V";
nickname = "My CR-V";
vin = "XX551234687687687654";
year = 2009;
}
Upvotes: 0
Views: 76
Reputation: 45500
I would probably use a for loop rather than a foreach since you need the array index, I would code it like this
NSMutableArray *vehiclesArray = [[NSMutableArray alloc]init];
for (int i = 0; i < [_infoFromJSON count]; i++)
{
//create vehicle
myVehicleObject *vehicleInMembersProfile = [[myVehicleObject alloc] init];
vehicleInMembersProfile.make = _infoFromJSON[i][@"make"];
vehicleInMembersProfile.carName = _infoFromJSON[i][@"nickname"];
vehicleInMembersProfile.year = _infoFromJSON[i][@"year"];
//finally add the vehicle to the array
[vehiclesArray addObject:vehicleInMembersProfile] ;
}
I wasn't sure what myVehicleObject
was , and why is it the same type you are adding to itself, so I changed it to an array. But you get the point.
Upvotes: 1
Reputation: 237110
The error is that your class does not implement NSCopying.
However, there isn't any need to copy the object here. You're creating a new object each time through the loop. If you insert a copy, you're just pointlessly throwing away the original each time. The more likely cause if you're seeing odd loop behavior is that your loop is mixing up different kinds of enumeration, as pointed out by nhgrif. Instead of accessing [_infoFromJSON objectAtIndex:carCount]
, just use myDictionary
.
Upvotes: 2
Reputation: 62062
This may or may not be related to the problem, but your forin
loop is completely broken. Whether or not your incorrect usage is the actual cause of the problem, this is something you should definitely fix as it can do nothing but cause problems.
If you want to use indexOfObject:
to grab an object at an index of the array you're iterating through, you should use a regular for
loop:
for (int carCount=0; index < [_infoFromJSON count]; ++carCount) {
// loop body remains identical to what you have...
// except remove carCount++;
}
But for what you're doing, a forin
loop is indeed better, and forin
loops can be faster since they can be handled in batches. But if you're using a forin
loop, use the object you're defining in the loop declaration:
for(NSDictionary* myDictionary in _infoFromJSON) {
// myDictionary is a reference to an object in _infoFromJSON,
//for whatever given index it is currently working on
myVehicleObject *vehicleInMembersProfile = [[myVehicleObject alloc] init];
vehicleInMembersProfile.make = myDictionary[@"make"];
vehicleInMembersProfile.carName = myDictionary[@"nickname"];
vehicleInMembersProfile.year = myDictionary[@"year"];
[self.myVehicleObject addObject:vehicleInMembersProfile];
}
Upvotes: 6