In the header for NSLocale, currentLocale
is declared like this:
+ (id /* NSLocale * */)currentLocale; // an object representing the user's current locale
It's obvious that they are returning id
on purpose, but I'm curious why that would be necessary. Could this method ever return anything other than an NSLocale instance?
Back in the day, one used NSDictionary
objects for locale information. See, for example, the "Special Considerations" documented for -[NSString compare:options:range:locale:]
:
Special Considerations
Prior to OS X v10.5, the locale argument was an instance of
NSDictionary
. On OS X v10.5 and later, if you pass an instance ofNSDictionary
the current locale is used instead.
Some methods, such as -[NSDate dateWithNaturalLanguageString:locale:]
still take an NSDictionary
.
Other methods, such as many classes' -descriptionWithLocale:
, can take either.
Anyway, with the introduction of NSLocale
the types of various locale parameters was generalized to id
to accommodate either kind of object without breaking source compatibility. The return type of +[NSLocale currentLocale]
is similar generic so that it can be passed to methods that used to only take NSDictionary
objects.
Initializers (even convenience initializer) traditionally return id
. This prevents problems when you subclass. For instance, imagine this scenario:
@interface Foo : NSObject
- (Foo *)initWithBar:(Bar *)bar;
@end
@interface Baz : Foo
- (Baz *)initWithBar:(Bar *)bar;
@end
This would be a compiler error. You are redefining initWithBar:
to return a different type. But if you always return Foo*
, then Baz *baz = [Baz initWithBar:bar]
would fail because initWithBar:
returns a superclass.
To get yourself out of this problem, all initializers have historically returned id
if there's any chance the class will be subclassed (which is to say, you should really always do this).
Recently, clang added instancetype
, which solves this problem more elegantly by representing "the type of the current class." This is only useable in the interface. You can't declare variables to be of type instancetype
(I've actually wanted this in some cases…) id
is automatically promoted to instancetype
for methods that begin with init…
. Otherwise, you need to use it manually. Many older Cocoa interfaces haven't been updated yet, but they're slowly moving over to instancetype
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.