I am a little bit stubborn, but I want to understand weak and strong references well, so that's why I'm asking you once again.
Consider this:
__weak NSString* mySecondPointer = myText;
NSLog(@"myText: %@", myText);
The result is myText: (null)
and it is pretty obvious - weak reference is set to null just after assignment, cause there is no strong reference to the pointed object.
But in this case:
__strong NSString* strongPtr = [[NSString alloc] initWithFormat:@"mYTeSTteXt %d"];
// weak pointer points to the same object as strongPtr
__weak NSString* weakPtr = strongPtr;
if(strongPtr == weakPtr)
NSLog(@"They are pointing to the same obj");
NSLog(@"StrongPtr: %@", strongPtr);
NSLog(@"weakPtr: %@", weakPtr);
NSLog(@"Setting myText to different obj or nil");
// after line below, there is no strong referecene to the created object:
strongPtr = [[NSString alloc] initWithString:@"abc"]; // or myText=nil;
if(strongPtr == weakPtr)
NSLog(@"Are the same");
else
NSLog(@"Are NOT the same");
NSLog(@"StrongPtr: %@", strongPtr);
// Why weak pointer does not point to nul
NSLog(@"weakPtr: %@", weakPtr);
The output:
2013-03-07 09:20:24.141 XMLTest[20048:207] They are pointing to the same obj
2013-03-07 09:20:24.142 XMLTest[20048:207] StrongPtr: mYTeSTteXt 3
2013-03-07 09:20:24.142 XMLTest[20048:207] weakPtr: mYTeSTteXt 3
2013-03-07 09:20:24.143 XMLTest[20048:207] Setting myText to different obj or nil
2013-03-07 09:20:24.143 XMLTest[20048:207] Are NOT the same
2013-03-07 09:20:24.144 XMLTest[20048:207] StrongPtr: abc
2013-03-07 09:20:24.144 XMLTest[20048:207] weakPtr: mYTeSTteXt 3 // <== ??
My question:
Why after strongPtr = [[NSString alloc] initWithString:@"abc"];
weak pointer value is not changed to nil (why the object created at the beginning still exists in memory, despite it does not have any strong refs? -- or maybe it has?)
I have tried that one: (but it is not good for adding a comment I suppose). I have included the code where I am creating a strongPtr in @autorealesepool. I not sure if it is correct solution but it work...
__strong NSString* strongPtr;
__weak NSString* weakPtr;
@autoreleasepool {
strongPtr = [[NSString alloc] initWithFormat:@"mYTeSTteXt %d", 3];
// weak pointer point to object create above (there is still strong ref to this obj)
weakPtr = strongPtr;
if(strongPtr == weakPtr) NSLog(@"They are pointing to the same obj");
NSLog(@"StrongPtr: %@", strongPtr);
NSLog(@"weakPtr: %@", weakPtr);
NSLog(@"Setting myText to different obj or nil");
// after line below, there is no strong referecene to the created object:
strongPtr = [[NSString alloc] initWithString:@"abc"];
}
if(strongPtr == weakPtr)
NSLog(@"Are the same");
else
NSLog(@"Are NOT the same");
NSLog(@"StrongPtr: %@", strongPtr);
// Why weak pointer does not point to nul
NSLog(@"weakPtr: %@", weakPtr);
Output:
2013-03-07 09:58:14.601 XMLTest[20237:207] They are pointing to the same obj
2013-03-07 09:58:14.605 XMLTest[20237:207] StrongPtr: mYTeSTteXt 3
2013-03-07 09:58:14.605 XMLTest[20237:207] weakPtr: mYTeSTteXt 3
2013-03-07 09:58:14.606 XMLTest[20237:207] Setting myText to different obj or nil
2013-03-07 09:58:14.607 XMLTest[20237:207] Are NOT the same
2013-03-07 09:58:14.607 XMLTest[20237:207] StrongPtr: abc
2013-03-07 09:58:14.608 XMLTest[20237:207] weakPtr: (null)
From the assembly code it can be seen that accessing weakPtr
generates a objc_loadWeak
call.
According to the Clang documentation, objc_loadWeak
retains and autoreleases the object and is equivalent to
id objc_loadWeak(id *object) {
return objc_autorelease(objc_loadWeakRetained(object));
}
This (hopefully) explains why both
if(strongPtr == weakPtr) ...
and
NSLog(@"weakPtr: %@", weakPtr);
create additional autoreleased references.
This is not a special NSString
problem, I could reproduce the same behaviour with a custom (plain) class.