1

I'm wondering why do [NSDate distantPast] and [NSDate distantFuture] methods' return types are of type id? Why don't these methods return an NSDate pointer?

jscs
  • 63,694
  • 13
  • 151
  • 195
aslı
  • 8,740
  • 10
  • 59
  • 80
  • Related: [Class methods which create new instances](http://stackoverflow.com/q/5987969) – jscs Feb 08 '13 at 18:07
  • **Update:** As of right now, [they _do_ return `NSDate*`](https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/#//apple_ref/occ/clm/NSDate/distantFuture). – Ky - Dec 17 '15 at 23:17

4 Answers4

5

Because polymorphism is just valid in one way.

Let's say that you subclass NSDate and that you want to override that method. You must use the same signature so you'll do it with this signature:

-(NSDate*) distantPast;

But you'll not be able to assign the result of the expression to a pointer of the subclass type, and you'll need to downcast the result:

NSDateSubclass* ptr= (NSDateSubclass*)[someDateSubclassInstance distantPast];
// Downcasting is necessary here, it would give a warning or syntax error otherwise.

Even if you are sure that the returned object is a subclass of NSDate, you need to downcast the result. This is why all the methods that returns created objects, are declared to return an id.

Ramy Al Zuhouri
  • 21,580
  • 26
  • 105
  • 187
  • 1
    **Update:** As of right now, [they _do_ return `NSDate*`](https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/#//apple_ref/occ/clm/NSDate/distantFuture). – Ky - Dec 17 '15 at 23:18
  • Interesting. Depending on when it changed, it may have been more appropriate to use `__kindof NSDate*` for the return type. `__kindof` gives you the `id` behavior of being able to call "any" selector on the returned value, but restricts the possibilities to known subclasses, so you can do stuff like `[[SubclassDate distantPast] someMethodOnlyOnSubclassDate]` without casting. – rickster Nov 28 '18 at 22:18
2

NSDate is an abstract superclass, and distantPast or distantFuture return private subclasses of NSDate, and not an NSDate per se.

iluvcapra
  • 9,436
  • 2
  • 30
  • 32
1

I think that question is also like asking what should you return on an init method? An id or a pointer to our class.

Because it would be the same on that case you can consider it's some kind of standardization on Apple's part for class methods.

Fábio Oliveira
  • 2,346
  • 21
  • 30
1

There is no particular reason for this. The other poster pointed out that these methods might return a private subclass of NSDate, but a subclass of NSDate is still an NSDate. I'm guessing that these methods are old enough (i.e. NextStep, before Mac OS) that the reasons for the id return type is historical, and "lost to antiquity". (If you look at these methods in the Mac OS docs, it says they were defined in Mac OS 10.0)

I bet the old school approach was to use anonymous object pointers everywhere.

Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • I realized it later, I thought it too. But polymorphism is valid just in one way, so if you try to initialize a pointer of the subclass type using this method, you'll get a syntax error or warning, and you would need to downcast the return type. – Ramy Al Zuhouri Feb 08 '13 at 18:26
  • It's true that the class cluster is not the reason for a return type `id`. Returning a subclass through a superclass return type is valid: `- (NSArray *)myArrayProperty { return _myInternalArrayWhichIsActuallyMutable; }` is fine. It's inheritance that is the issue: if `+[NSArray array]` returned `(NSArray *)`, then `NSMutableArray * array = [NSMutableArray array];` would make the compiler complain. – jscs Feb 08 '13 at 18:35