Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

ataylor2009

macrumors member
Original poster
Jan 27, 2009
78
0
I want to create a bunch of objects (say 100+) and store them in an array. Each object has, say, 10 instance variables, all declared as properties. My question is, how do I access a specific object.property in the array? In other words, I want to access the bar property in object foo, which is stored at baz[26].

Is it just baz[26].foo.bar = newValue?

Or do I have to do something like

tempValue = [baz objectAtIndex: 26];
tempValue.bar = newValue;
[baz replaceObjectAtIndex: 26 withObject: tempValue];


I really hope it's the first one and not the second.

Thanks in advance for your help.
 

TEG

macrumors 604
Jan 21, 2002
6,625
173
Langley, Washington
I believe it is something like the first one, but you can omit the "foo" from it, since that is just a label for something located in the 26th position on the array. So baz[26].bar = newValue? is very close to what you need.

TEG
 

Krevnik

macrumors 601
Sep 8, 2003
4,101
1,312
Real answer is: Neither.

The first one won't work at all (array operator doesn't work on Obj-C objects), and the second one is redundant. It works, but it has too much code and does operations it doesn't need to.

Either one of these will work:

Code:
  tempValue = [baz objectAtIndex:26];
  tempValue.bar = newValue;

Code:
  [baz objectAtIndex:26].bar = newValue;

They work because you store a reference to the object in the array. The array retains the object rather than making a copy. When you ask for an object at an index, it simply returns that reference again. You can edit in-place without having to copy the object back into the array (because it already has a reference).
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
I would say that you should pick the "style" you want to use and stick with it. If you want to use Objects, etc. store them in an NS(Mutable)Array. If you want to use C-style arrays, you can use structs, etc. Mixing them just gets ugly. I will also use this as an excuse to speak unkindly about the dot notation, as it only stands to introduce ambiguity in my mind. Sending a message is much clearer in its intent when reading the code. If you see a dot, that says to me that you are accessing the element of a structure that you have a local copy of. A message pass is clearly going to an Object *.

I would say that:
Code:
[[baz objectAtIndex: 26] setBar: newValue];

is concise, easy to read, and clear that you are modifying the field of an object via a message pass.

A lot of this is just a matter of style, and this is just my opinion on the matter. I'm sure others will disagree.

-Lee

Edit: Krevnik beat me to it, and stuck with the dot-notation that the OP was using.
 

Krevnik

macrumors 601
Sep 8, 2003
4,101
1,312
A lot of this is just a matter of style, and this is just my opinion on the matter. I'm sure others will disagree.

Pretty much the only extra comment for the OP I have is that using structs/c-arrays for Obj-C objects is dangerous. Yes you can do it, but then you become responsible for managing the lifetime of the object while it lives in the struct/c-array.

I prefer to keep Obj-C objects within other Obj-C objects, as it makes auditing easier, and leaks less likely. The moment I have to think heavily on the lifetime of an object is when I make mistakes, and C data types holding Obj-C objects make me think heavily on the lifetime of the object.

So don't mix the two if at all possible. That is the way to madness.
 

ataylor2009

macrumors member
Original poster
Jan 27, 2009
78
0
Krevnik:

Exactly what I needed. Thank you for the assistance.

Actually, thanks to all who contributed. The dialog is nearly as helpful as the final solution in most cases.
 

ataylor2009

macrumors member
Original poster
Jan 27, 2009
78
0
I was planning on using an NSArray (or NSMutableArray) to hold the objects. If I said something in my original post that led you to believe otherwise, then I misspoke (or miswrote. Whatever.).

Thank you all again for your help.
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
I was planning on using an NSArray (or NSMutableArray) to hold the objects. If I said something in my original post that led you to believe otherwise, then I misspoke (or miswrote. Whatever.).

Thank you all again for your help.

It was just a bit ambiguous... the only thing you said was "in an array", and the confusion was somewhat exacerbated by the use of [], which will only work on C-style arrays, not Objects (as has been mentioned above). No harm, no foul... it just might be best to be explicit in the future so people know "what's on the table", so to speak.

-Lee
 

ataylor2009

macrumors member
Original poster
Jan 27, 2009
78
0
Okay, I've written some code, but I'm clearly doing something wrong. Here's my first attempt:

Code:
[rooms objectAtIndex: roomCount].roomID = newID;

where rooms is an instance of NSMutableArray, roomCount is an integer, roomID is an instance variable of type int in my Room object, and newID is an instance of NSNumber. The error message I'm getting when I compile is

"error: request for member 'roomID' in something not a structure or union"

What am I missing here? As usual, thank you all in advance for your guidance.
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
Code:
[[rooms objectAtIndex:roomCount] setRoomID: newID];

Is the de-sugared code you're running. Does your room class have a setRoomID: method? Can you post the class declaration?

-Lee
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
You need to create an accessor method to assign the value of roomID, unless you declare it as a property. Also int != NSNumber. You must use the intValue method on an NSNumber.
 

ataylor2009

macrumors member
Original poster
Jan 27, 2009
78
0
The class declaration is

Code:
@interface Room : NSObject
{
	int		roomID;
	NSString	*name;
	NSString	*desc;
	int		N, E, S, W, U, D;
}

@property int		roomID, N, E, S, W, U, D;
@property (copy, nonatomic) NSString	 *name, *desc;

@end

I thought by using the @property directive (and @synthesize in the *.m file) I was spared the hassle of writing accessor methods? Doesn't the property feature create setroomID: and roomID: methods for me?
 

eddietr

macrumors 6502a
Oct 29, 2006
807
0
Virginia
Code:
[rooms objectAtIndex: roomCount].roomID = newID;

So, I think, at least with Apple's GCC that ships with the current dev tools, it is still not possible to mix brackets and dots quite this way. You can mix them in other ways, and you would think this way would work, but it doesn't.

I used to know exactly why this is the case, but I can't remember right now.

But you can do something like:

Code:
Room* room = [rooms objectAtIndex: roomCount];
room.roomID = [newID intValue];
// or [room setRoomID:[newID intValue]];

or

Code:
[[rooms objectAtIndex: roomCount] setRoomID: [newID intValue]] // yuck!
 

ataylor2009

macrumors member
Original poster
Jan 27, 2009
78
0
...Also int != NSNumber. You must use the intValue method on an NSNumber.

Doh! There were so many errors when I compiled my test code the first time that I totally missed this. Thanks for pointing it out.

Originally I was going to store all the data in an array (as opposed to storing the data in an object in an array), which is why I was converting to NSNumber objects. I can remove that bit of deadweight now.

Thanks again.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.