1

I'm currently reading The Big Nerd Ranch Guide on Objective C programming and I'm having trouble understanding a section in Chapter 13, Objects which is providing bad examples of Messages:

NSDate *now = [NSDate date];
double seconds = [now timeIntervalSince1970];

This is firstly a correct example of using messages in Objc. The first line creates a pointer to an NSDate object using the variable now and the NSDate type declaration. It is now an instance of NSDate. It was explained to me that if you are to print now, it will display the output of the NSDate date method. This is where things start to get a little weird for me. It seems odd that you would have a variable pointing both to an instance, and a function output if printed. But that's okay. Moving on.

The second line creates a variable called seconds, which is of type "double" and is going to obtain a value that the timeIntervalSince1970 method of NSDate instance now outputs.

Here is where the author introduces examples of bad messages:

double testSeconds = [NSDate timeIntervalSince1970];
NSDate *testNow = [now date];

He explains the errors as follows:

First Line:

"The Error is clear, the receiver in this message send is the NSDate class, so the selector should be the name of an NSDate class method. This selector is not."

Ok. This makes sense. An invalid method. Next. .

Second Line:

"This error is less clear: It is telling you that NSDate has no instance method whose name matches the date selector."

Wait, what? Isn't now a pointer to an instance of NSDate? Shouldn't you be able to call the date method from an instance of NSDate? I don't get it.

The book does not explain any more than what I've quoted above, so I'm sure it's something stupid and basic I'm not getting. I hope this isn't too specific or unhelpful to others. I'll delete the submission if asked. Thank you.

Lars Blumberg
  • 19,326
  • 11
  • 90
  • 127
Micrified
  • 3,338
  • 4
  • 33
  • 59

1 Answers1

2

The variable now points to an instance of NSDate. The method date is not defined on instances of NSDate but on the class itself. Hence date is a class method and not an instance method. Unlike other programming languages Objective-C does not inherit class methods to their class instances.

Vice versa instance methods cannot be called on classes. This said timeIntervalSince1970 cannot be called on the class NSDate as this method is an instance method. This is due to the circumstances that instances usually manage an instance state. Instance methods do operate on this instance state, namely reading and modifying their instance variables. Back to your example: The instance method timeIntervalSince1970 calculates the difference between 01/01/1970 and a concrete, instantiated date. So if you would be able to call timeIntervalSince1970 on class level there's no chance to calculate a difference of dates as the class NSDate doesn't carry any date information (the instance state!) such as the day, month, year and the time.

To sum up: Instance methods cannot be called on classes. This isn't supported by any programing language I am aware of. Calling class methods on instances is however supported by some programing language although there's typically no need for doing so and sometimes it even lowers code readability. However Objective-C doesn't support those calls neither.

Lars Blumberg
  • 19,326
  • 11
  • 90
  • 127
  • So instances of NSDate, don't "inherit" NSDate class methods? And instance methods are only available to instances of objects? This seems so confusing. Coming from python where a class instance inherited all class methods. And where instance methods are unheard of. I think I'll have to read the chapter again. Thanks. . . – Micrified Sep 22 '14 at 05:02
  • Forgot to tag in Original reply – Micrified Sep 22 '14 at 05:12
  • @Owatch No, `NSDate` does not inherit its class methods to its instances. And yes, instance methods are only available to instances of classes. Please be aware of the correct wording: _Instance of class_ = _object_. Please see also my updated answer regarding your questions. – Lars Blumberg Sep 22 '14 at 07:32
  • @Owatch Are you sure that Python doesn't have instance methods? Also Python (unfortunately) isn't a language I've used so far, I found that instance methods do exist: http://stackoverflow.com/questions/17134653/difference-between-class-and-instance-methods – Lars Blumberg Sep 22 '14 at 07:37
  • Well, when the linked example discusses instance methods, it's not that separate methods exist for instances, but more that certain methods will not work unless an instance exists. The use of 'self' in Python is useful in instances because you can assign local variables to individual instances. If the method of an object sets a variable NAME to self.NAME. It makes self.NAME accessible across all methods of the object. Rather than localized to that method. It seems I wasn't thinking of instance methods the same way. Instance methods only work when an instance exists. – Micrified Sep 23 '14 at 00:50
  • Not somehow appear when an instance is created as I was incorrectly interpreting it before, even if that's silly. – Micrified Sep 23 '14 at 00:52
  • @Owatch: Methods on classes and methods on an instance are different in Python. If you try to call a method on an instance that is actually defined on the class, you get a method with one less parameter (a bound method, where the first parameter is bound to the instance), which is different than if you have a method defined on the instance directly, in which case there is no argument for the instance. – newacct Sep 26 '14 at 08:30