When is a weak link updated to zero in Objective-C?

Consider the following two cases:

// case 1 NSObject *strongOne = [[NSObject alloc] init]; NSObject * __weak weakOne = strongOne; if (weakOne) { NSLog(@"weakOne is not nil."); } else { NSLog(@"weakOne is nil."); } strongOne = nil; if (weakOne) { NSLog(@"weakOne is not nil."); } else { NSLog(@"weakOne is nil."); } 

Outputs the following:

 weakOne is not nil. weakOne is not nil. 

and

 // case 2 NSObject *strongOne = [[NSObject alloc] init]; NSObject * __weak weakOne = strongOne; strongOne = nil; if (weakOne) { NSLog(@"weakOne is not nil."); } else { NSLog(@"weakOne is nil."); } 

Outputs the following:

 weakOne is nil. 

As far as I know, when strongOne freed, a weak reference to the same object should be updated to nil .

My question is: Why does this only happen in case 2 ?

+4
source share
2 answers

I think this is due to the fact that when you get into the if statement using the weakOne function, you increase the save count in the autocomplete pool; therefore, a weak pointer will not be zero until the pool of autoresists is drained.

  // Try this NSObject *strongOne = [[NSObject alloc] init]; NSObject * __weak weakOne = strongOne; //count 1 @autoreleasepool { if (weakOne) { NSLog(@"weakOne is not nil."); //count 2 } else { NSLog(@"weakOne is nil."); } strongOne = nil; // count 1 if (weakOne) { NSLog(@"weakOne is not nil."); } else { NSLog(@"weakOne is nil."); } } // count 0, therefore the weakOne become nil if (weakOne) { NSLog(@"weakOne is not nil."); } else { NSLog(@"weakOne is nil."); } 
+1
source

As far as I know, when strongOne is released, a weak reference to the same object should be updated to zero.

It is right. But you do not free the object, when you set strongOne to nil, you just change the pointer. ARC probably calls the autorelease on the strongOne object dots, so the object will not actually be released until a later time, when the auto-resource pool is deleted.

Why does this happen only in case 2?

It looks like ARC sends release in this case, so the object is freed, and your weak link is updated immediately.

Or maybe the compiler notices that you never use strongOne before setting it to nil, except to assign it to a weak pointer and therefore decide not to highlight the object in the first place. Go through this code and see if strongOne value other than zero.

+1
source

Source: https://habr.com/ru/post/1495413/


All Articles