On Sun, Aug 31, 2008 at 4:34 AM, Jon Davis <[EMAIL PROTECTED]> 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 protected]) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
