I had a hard to track bug which only appeared in the Release build of my app, but not in the Debug build. The relevant difference between the builds turned out to be that the Debug build was compiled without any compiler optimization, whereas the Release build was compiled with -O (the bug was reproducible on all other optimization settings as well). This is all on LLVM.
In my view controller I have a property self.basicInfoContainerView defined as:
@property (weak, nonatomic) IBOutlet UIView *basicInfoContainerView;
I then removed the subview from one view, and added it onto another.
[self.basicInfoContainerView removeFromSuperview];
[self.infoTextView addSubview:self.basicInfoContainerView];
Depending on the compiler optimization level, different things happened.
With optimization on: as soon as the view was removed from its superview, the view was deallocated and self.basicInfoContainerView was a zero’ed, and as a result was not added as a subview to the new view.
With optimization off: the subview was not immediately deallocated and was successfully added as a subview to the new view.
(When I changed the property storage qualifier to strong, the view survived in both cases, but even though that solved the problem, but that’s not really my question.)
I would love someone to help me understand what is really going on here. Why does weak not immediately release my view (and zero the pointer if retain count == 0) when compiler optimization is turned off?
It’s really not unusual to see non-optimized code that keeps extra local (and strong) references to objects. So your unoptimized code must have a local strong reference to this ‘basicInfoContainerView’. That reference stays in scope through the method, and isn’t being released probably until the method returns.
This is really just an accident of sorts that is masking a real bug in your code. The fact of the matter is as soon as you do
[self.basicInfoContainerView removeFromSuperview], you can’t expect that your basicInfoContainerView will survive, because you don’t have any explicit strong reference to that view any more.The way to fix this, of course, is to create an explicit strong reference to that view. Then you’ve made your intention clear to the compiler, and you should get the result you want whether the code is optimized or not:
Hope that helps.