Crash when printing variable address wich became invalid


#1

Hi all,

In the book it is explained that when we change __weak attribute of container member to __unsafe_unretained, the statements

backpack = nil; NSLog("@Container: %@", [calculator container]);
cause application to crash. That’s perfectly understandable - [calculator container] returns a pointer to an object that does not exists anymore, NSLog calls description method of that object that causes crash.
What I don’t understand is if I rewrite NSLog just to output the pointer value, in my understanding nothing wrong should happen - it should simply print the address of now invalid object but it’s OK. What happens, the program still crashes - why? NSLog does not need to call any method of that object in this case - it suppose only to print its address:

		backpack = nil;
		NSLog(@"Container: %p", [calculator container]);

#2

The calculator is probably gone, so sending it a message to resolve its container is causing the crash.


#3

Yeah you are right. It should just log the address of the non-existent Backpack without crashing . I don’t think that the calculator immediately gets issued a dealloc after we do backpack=nil. Just after this line, if we send any message to the calculator reference, you wouldn’t see blank or nothing in the console. [calculator container] was a special case that signified that the Backpack object has been destroyed, thus giving a value (null). But calculator object still remains alive until we reach the end of autoreleasepool directive.
What I couldn’t get is the meaning of (null) when you log [calculator container] when you set container as __unsafe_unretained.
Please help me clear the difference between (null), even though was not part of the output.

@interface BNRItem : NSObject
{
    NSString *itemName;
    int valueInDollars;
    NSString *serialNumber;
    NSDate *dateCreated;
    
    //Used for Retain cycle 
    __unsafe_unretained BNRItem *container;
    BNRItem *containedItem;
}

In main.m file

 [backpack setContainedItem:calculator];
  backpack=nil; //Destroying Backpack object
NSLog(@"%@",[calculator container]);

Output:

2013-06-16 19:25:34.508 BNRItem[554:303] Destroyed object: BACKPACK( ) having as cost.Date of listing: 2013-06-16 13:55:34 +0000
2013-06-16 19:25:34.509 BNRItem[554:303] (null)((null)) having as cost.Date of listing: (null)
2013-06-16 19:25:34.510 BNRItem[554:303] Destroyed object: CALCULATOR( ) having as cost.Date of listing: 2013-06-16 13:55:34 +0000