I'm trying to better understand Strong References, but in the context of a particular example that I will list below.
Lets say that I have a global variable called gPrefs. It's of type Preference Class, a custom class I made.
I've declared in its interface the following...
@property (strong) NSURL *masterFolder;
This is a pointer to a NSURL Object. I have given it (strong) reference meaning it will stick around and not release it's memory.
Now lets say I have an instance function somewhere else entirely that looks like the following below.
- (IBAction)masterDataSelectButtonAction:(id)sender
{
NSOpenPanel *openPanel = [NSOpenPanel openPanel];//creates an open panel.
[openPanel setCanChooseDirectories:YES];
[openPanel setCanChooseFiles:NO];
NSInteger panelResult = [openPanel runModal];
if(panelResult == NSFileHandlingPanelCancelButton){
NSLog(@"masterDataSelectButtonAction -> Cancel Button Pressed");
return;
}
if(panelResult == NSFileHandlingPanelOKButton){
NSLog(@"masterDataSelectButtonAction-> Ok Button Pressed");
NSURL *theUrl = [openPanel URL];
gPrefs.masterFolder = theUrl; //Setting (strong ref) point to local.
[_masterDataLabel setStringValue:[gPrefs.masterFolder absoluteString]];
}
}
If the person pressed the OK button of the panel, I create a local pointer instance variable called theUrl. I then set the global variables masterFolder pointer to the local instance variables pointer.
If I understand correctly ARC is supposed to release objects at the end of functions when it deems it's not being used anymore.
Therefore theUrl should be released at the end of the function.
However, if I understand (strong) reference, the compiler perhaps is smart enough to realize that since I changed the global preferences pointer to a different pointer it will keep the other pointers reference in memory alive (or retain it).
If I had not declared my masterFolder pointer as (strong) would the masterFolder pointer be nil after the function ended?
My experiments show that keeping it (strong) seems to retain the value from the localInstance pointer despite reaching the end of the local instance function.
My question is why? Even if masterFolder is a strong reference, if I assigned it to a localInstance pointer and that pointer is removed at the end of the Instance function, why did the value of masterFolder not NIL out when I read from it again outside the instance function anywhere else.
My understanding of (strong) references is a bit (weak). No pun intended.
NSURL *theUrl = [openPanel URL];
theURL
is in the scope of the function (or within the if
block, but that doesn't make a difference in this example). The object that theURL
is pointing to is on the heap. At the end of the function, when theURL
goes out of scope, the reference count of the object on the heap will be decreased by 1 (because theURL
is a strong reference to the object. If at that point the reference count goes to 0, the object is released. In your case there is at least one other strong reference to the object (in your global singleton) so the object stays alive. The object on the heap is not local to anything, therefor the memory does not go out of scope.
If you global singleton has a weak reference it will automatically be set to nil
once the object's reference count reaches 0 and the object is released.