Re: (Newb) Populate NSMutableDictioanry with NSArray
Re: (Newb) Populate NSMutableDictioanry with NSArray
- Subject: Re: (Newb) Populate NSMutableDictioanry with NSArray
- From: "Michael Ash" <email@hidden>
- Date: Sun, 31 Aug 2008 23:03:19 -0400
On Sun, Aug 31, 2008 at 4:34 AM, Jon Davis <email@hidden> wrote:
> I came across tutorial code that looked sort of like this:
>
> NSMutableDictionary * myCollection;
> myCollection = [[NSArray alloc] initWithObjects:@"a", @"b", @"c", nil];
>
> The types are not the same. So my first question is, is this a bug? And if
> so, why didn't the compiler catch it? I come from C# so unless
> NSMutableDictionary inherits NSArray this logic would not compile.
>
> If it is not a bug, can someone confirm that NSDictionary is not just used
> for key/value pairs but as simple list types, too? Otherwise, why would
> myCollection above be declared as an NSMutableDictionary?
The important thing to understand about this case is that Objective-C
does not have constructors as are found in certain popular object
oriented languages. The "alloc" and "initWithObjects:" methods you're
calling are just regular old methods. Although they create a new
object for you, there's nothing special about them, or different from
other methods.
With that in mind, let's look at the declaration of the
"initWithObjects:" method:
- (id)initWithObjects:(id)firstObj, ... NS_REQUIRES_NIL_TERMINATION;
And right there is your answer as to why you didn't get an error. It's
typed to return "id", which of course is Objective-C speak for "any
object". It's never an error, or a warning, to assign a value of type
id to a more specific type. So your assignment of a value of type id
to a variable of type NSMutableDictionary is perfectly valid.
This just raises a new question, though: why does this method return
"id" instead of NSArray *? The answer to this is subclasses, of which
there is a great example in the form of NSMutableArray. Imagine if the
method was typed to return NSArray *. Then you wrote code like this:
NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:@"a",
@"b", nil];
This is perfectly legal code. But the compiler will whine at you.
You're taking a value of type NSArray *, and assigning it to
NSMutableArray *. Since NSMutableArray is a more specific type than
NSArray, this assignment is considered unsafe, and you get a warning.
But the code is perfectly fine. To avoid this problem, and to allow
initializers to work with subclasses, they generally return "id"
rather than a specific class type.
Objective-C is pretty different from C#. In particular, its type
system is a lot more dynamic and runtime oriented. The compiler will
only catch superficial errors for you at compile time, as compared to
environments like C# where compile time type checking is much more
rigorous. Opinions vary as to which is better. Personally speaking,
I've never had a type-based bug in Objective-C code that a stricter
language would have caught but which took me a long time to find in
Objective-C. These things tend to show up almost immediately in
testing. And while they can be confusing if you're just starting out,
with a little experience they tend to be easy to track down.
Mike
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden