9

I have a class A with a property NSString *name. If have an NSArray and add many A objects into this array, is casting necessary each time I retrieve an object? i.e.

NSString* n = (NSString*)[arr objectAtIndex:1];

Or is there a another way to do it kind of like in java where you have ArrayList<A> arr?

4 Answers 4

20

NSArray do not store information about the types of objects contained in them. If you know for sure the types of objects in your array, you can perform a cast, either implicitly or explicitly:

NSString *n = [arr objectAtIndex:1];  // implicit type conversion (coercion) from id to NSString*
NSString *n = (NSString *)[arr objectAtIndex:1];  // explicit cast

There's no difference in runtime cost between implicit and explicit casts, it's just a matter of style. If you get the type wrong, then what is very likely going to happen is that you'll get the dreaded unrecognized selector sent to instance 0x12345678 exception.

If you have a heterogeneous array of different types of objects, you need to use the isKindOfClass: method to test the class of the object:

id obj = [arr objectAtIndex:1];
if ([obj isKindOfClass:[NSString class] ])
{
    // It's an NSString, do something with it...
    NSString *str = obj;
    ...
}
Sign up to request clarification or add additional context in comments.

6 Comments

It's worth noting that there is no way to distinguish between NSStrings and NSMutableStrings at runtime — they all answer YES to isKindOfClass: [NSMutableString class].
@Chuck: I didn't know that. How come?
@Chuck: I noticed that NSString also returns YES to [myNSString respondsToSelector: @"appendFormat:];. ISTM that mutable and immutable strings are both implemented by __NSCFString and that has some internal flag telling it whether is it mutable or not. If you call [myNSString appendFormat: @"world"]; you get an exception, but not one that indicates it does not respond to the selector. Apparently appendFormat: checks the immutable flag and if it is set, it raises an exception. Mutable and immutable strings are, de facto, the same class, __NSCFString.
@Chuck: Ok, there is also __NSCFConstantString, for string literals.
@Rudy: You're right. They're both implemented "on top of" CFString, whose code you can look at; it does indeed have a mutable flag. Some (all?) of the mutating functions call CFAssertIsStringAndMutable(), which, as you might guess, uses CFAssert to check that the string is mutable.
|
11

NSArray's objectAtIndex: returns a variable of type id. This would be roughly equivalent to returning an Object in Java—"we can't guarantee much about this variable's type." In Objective-C however, you can send messages to id variables without the compiler complaining. So, because you know that the array only contains A instances, you're good to send it the name message. For example, the following will compile without warning:

NSString *name = [[array objectAtIndex:0] name];

However, if you want to use dot notation (e.g. [array objectAtIndex:0].name), you'll need to cast the id to an A * as shown here:

NSString *name = ((A *)[array objectAtIndex:0]).name;

1 Comment

perfect.. just the info I was looking for
1

This is the way to do it. You can actually do the above operation without casting the return since you're reading it into a NSString anyway.

Comments

-3

this is the way:

NSMutableArray  *objectsArray = [[NSMutableArray  alloc] init];

A *a= [[A alloc] init];

[objectsArray addObject:a];

[a release];

You don't need to worry about the proprety type

4 Comments

Actually no, adding to the array retains the object so after that snippet you have a retain number of +2, so you would actually need to remove the item and release it in order for it not to leak, all and all this is bad practice, I should have said this code can lead to leaks..
Daniel is right to point out that this is poor style. There is only one reference to the instance of A, which is through the array, but both the array and the allocing code have ownership claims on it. /cc @Chuck
Oh, terribly sorry. Long day. Ignore me.
Thx for pointing that out: But it wasn't really the point here!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.