user6631314
user6631314

Reputation: 1970

IOS/Objective-C: Get value of property of object in array

I am trying to grab a relationship property of an object from a mutable array.

theNewItems[0].step is giving the error,  Property 'step' found on object of type id.

Here is how I created the array:

 NSMutableArray* theNewItems = [NSMutableArray arrayWithCapacity:20];

 [theNewItems addObject:_itemsOnLoad[0]];
 [theNewItems addObject:_itemsOnLoad[1]];
 [theNewItems addObject:_itemsOnLoad[2]];

And here is how the array logs out

<Items: 0x1706842e0> (entity: Items; id: 0xd000000001900004 <x-coredata://AFF50577-0975-4124-AC70-074F355B73A0/Steps/p100> ; data: {
    item = "0xd000000016000000 <x-coredata://AFF50577-0975-4124-AC70-074F355B73A0/Dare/p1408>";
    sid = 545;
    step = "step three";
    wasdeleted = nil;
    whenadded = nil;
}),
    <Items: 0x170684330> (entity: Items; id: 0xd000000001840004 <x-coredata://AFF50577-0975-4124-AC70-074F355B73A0/Steps/p97> ; data: {
    item = "0xd000000016000000 <x-coredata://AFF50577-0975-4124-AC70-074F355B73A0/Dare/p1408>";
    sid = 544;
    step = "step two";
    wasdeleted = nil;
    whenadded = nil;
}),
    <Items: 0x170684380> (entity: Items; id: 0xd000000001780004 <x-coredata://AFF50577-0975-4124-AC70-074F355B73A0/Steps/p94> ; data: {
    item = "0xd000000016000000 <x-coredata://AFF50577-0975-4124-AC70-074F355B73A0/Dare/p1408>";
    sid = 543;
    step = "step one";
    wasdeleted = nil;
    whenadded = nil;
})
)}

Should I be creating the mutablearray differently? Or how can I grab the property "step"?

Thanks in advance for any suggestions.

Upvotes: 0

Views: 1178

Answers (2)

DonMag
DonMag

Reputation: 77690

For clarification...

An NSArray (mutable or not) can hold objects of any type. So, when you "get" an object from the array, the compiler needs to know what you are getting.

Example:

NSMutableArray *a = [NSMutableArray arrayWithCapacity:40];
[a addObject:[UIView new]];     // add a UIView
[a addObject:@"A string"];      // add a NSString
[a addObject:@100];             // add a NSNumber

You now have an array with a View, a String and a Number. If you try to do this:

UIView *v = a[0];
NSString *s = a[1];
NSNumber *n = a[2];

You'll get warnings because while the types are correct, the compiler doesn't know that.

To actually use the objects you've stored in the array, you have to cast them. So, with the same example data:

UIView *v = (USView *)a[0];
NSString *s = (NSString *)a[1];
NSNumber *n = (NSNumber *)a[2];

is fine... you can use your v s and n objects as you'd expect.

For your specific object type of Items, you could:

Items *thisItem = (Items *)theNewItems[0];
NSString *theStep =  thisItem.step;

or, more concisely:

NSString *theStep = ((Items *)theNewItems[0]).step;

In 2015, Apple introduced "Lightweight Generics" into Objective-C. This allows you to declare an array of type:

NSMutableArray <Items *> *theNewItems = [NSMutableArray arrayWithCapacity:20];

[theNewItems addObject:_itemsOnLoad[0]];
[theNewItems addObject:_itemsOnLoad[1]];
[theNewItems addObject:_itemsOnLoad[2]];

NSString *theStep = theNewItems[0].step;

And no more casting. Note that you still add your Items objects to the array in the same manner.

Another note: Reading around you'll find some debate about arrayWithCapacity. The most reliable info I've found explains that it perhaps used to make memory management a bit more efficient, but these days it's simply a "hint" and, really, only makes for readability as in:

"When I review my code, I see that I'm expecting this array to hold 40 objects."

It does not, however, pre-allocate memory... nor does it limit the array to 40 elements - the array will still expand as you continue to add objects to it.

Upvotes: 2

Harry Singh
Harry Singh

Reputation: 816

You don't need to use arrayWithCapacity you can just make an array using [[NSMutableArray alloc] init]; which will have no limit on capacity.

To get the property just say ((Items *)theNewItems[x]).step, x being the index at which you want the property. Also if you want to skip the casting step when pulling the object out of the array define your array as NSMutableArray<Items *> * theNewItems = [[NSMutablearray alloc] init] then you can just say theNewItems[x].step

Upvotes: 0

Related Questions