-1

I'm working my way through Big Nerd Ranch's Objective C Programming (2nd Edition) and just came across this example in Chapter 15 (Objects and Memory):

NSDate *currentTime = [NSDate date]; //currentTime points to date object at some address ("A")
NSLog(@"currentTime's value is %p.\n", currentTime);

sleep(2);

currentTime = [NSDate date]; //currentTime now points to date object at different address ("B")
NSLog(@"currentTime's value is now %p.\n", currentTime);[/code]

I'd like to understand why currentTime changed from address A to address B when it was assigned a new date. Why didn't it write the data for the 2nd date into the memory location used for the 1st date (at address A)?

This c code (edit: which is embarrassingly bad but I will leave as originally-written so the comments/answers make sense):

int *i = 10;
i = 12;

doesn't change the value of &i or allocate any additional memory, so what gives?

Fred Hamilton
  • 697
  • 3
  • 9
  • 22
  • 5
    `int *i = 10;` isn't even valid; if you declare `i` as a pointer, then `i = 12;` isn't valid either. Pointers in Objective-C behave **exactly the same** as they behave in C, since Objective-C's pointers **are** just plain C pointers. It seems that you're confusing the pointer itself with the memory it points to. When you do `currentTime = [NSDate date];`, then you are re-assigning the pointer itself, to new, freshly allocated `NSDate` object. "Why didn't it write the data for the 2nd date into the memory location used for the 1st date" – merely because you didn't dereference the pointer. – The Paramagnetic Croissant Jan 31 '15 at 20:00
  • (what you are talking about would be described by something like `*currentTime = *[NSDate date];`, but that's not valid, because Objective-C objects cannot be passed around and copied by-value; only pointers to them are permitted. And it would leak the memory allocated for the new object anyway.) – The Paramagnetic Croissant Jan 31 '15 at 20:01
  • Thanks. I really need to start testing "working" code before I post it here - I'm too new to this to not make mistakes. New question: How come you didn't write this as an answer so you can get some more rep? – Fred Hamilton Jan 31 '15 at 20:05
  • 1
    this has already been discussed a thousand and one times on Stack Overflow. it's not really worth writing yet another answer, re-iterating the problem over and over again, when there have already been significantly better and more detailed answers. you'll need to search for those instead. also, do yourself a favor: don't try to jump into Objective-C until you aren't familiar with fundamental concepts of C (e. g. pointers). You will only be more confused by all the advanced(-ish) stuff like strong vs. weak pointers, method dispatch, etc. that Objective-C presents. – The Paramagnetic Croissant Jan 31 '15 at 20:08
  • 4
    [What are the barriers to understanding pointers and what can be done to overcome them?](http://stackoverflow.com/q/5727) – jscs Jan 31 '15 at 20:10
  • 2
    `NSDate *currentTime` will create a 32/64 bit integer, which contains the memory location where the date is stored. When you assign a new date to `currentTime` you are writing a different memory location to the variable. Make sense? I find pointers are easier to understand when you learn what they technically do, instead of trying to describe them metaphorically. – Abhi Beckert Jan 31 '15 at 20:22
  • *don't try to jump into Objective-C until you aren't familiar with fundamental concepts of C (e. g. pointers).* That is a very important statement! Objective-C is not a beginner's language -- you should understand (at least) the basic concepts of pointers and objects first. – Hot Licks Feb 03 '15 at 23:55
  • Yes, my c pointer example was embarrassing, but I'm not sure why the question was voted down. I think the Objective-C portion of the question is a pretty good one because it's not obvious (at least to the beginner), and @jeffamaphone's answer and example do a great job of showing exactly what is happening. – Fred Hamilton Feb 05 '15 at 05:21

2 Answers2

3

Why didn't it write the data for the 2nd date into the memory location used for the 1st date (at address A)?

You've declared currentTime as a pointer to an NSDate object, as you should. The answer to your question lies in what [NSDate date] does. It's declared in NSDate.h as:

@interface NSDate (NSDateCreation)
+ (instancetype)date;
...

These sorts of class methods marked as returning an instancetype indicate that the method is conceptually a factory method. In this case, it is shorthand for [[NSDate alloc] init]. alloc allocates memory for a new object, and init initializes it.

So when you assign a new value to the NSDate pointer, the old object is implicitly released (since, presumably, you're using ARC and you declared currentTime as an implicit strong reference) and the pointer is updated to point to the newly created object.

This shouldn't be any different from the way C pointers behave. It's analogous to:

CDate *currentTime = malloc(sizeof(CDate));
CDate_Initialize(currentTime);

sleep(2);

free(currentTime);
currentTime = malloc(sizeof(CDate));
CDate_Initialize(currentTime); 
...
i_am_jorf
  • 53,608
  • 15
  • 131
  • 222
  • Excellent - you answered the question I was trying to answer *despite* my embarassingly bad c example. Great c example as well - I learned even more about memory handling. Thanks. – Fred Hamilton Jan 31 '15 at 20:13
0

[NSDate date]; defines allocates a new address which you assign to currentTime assigning it second time overwrites its first value

hariszaman
  • 8,202
  • 2
  • 40
  • 59