Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent ARC to nil a weak ivar right after assignment (in release builds) [duplicate]

I have a auto-synthesized readonly & weak property:

@property (nonatomic, readonly, weak) KTWindowController* windowController;

I assign the synthesized ivar and then add it to an array:

_windowController = [KTWindowController controller];
[self addSubController:_windowController];

This works fine in Debug builds. But I got a report that in release (ad hoc) builds this will immediately nil the _windowController and then it tries to add nil to the array, crashing the app.

What specific setting (optimization level?) in a release (ad hoc) build changes this behavior compared to Debug builds?

It strikes me as odd that this behavior would change from Debug to Release builds. But I was able to reproduce this behavior, and it actually makes sense - just not when it's not coherent with what happens in debug builds.

The suggested workaround:

KTWindowController* windowController = [KTWindowController controller];
[self addSubController:windowController];
_windowController = windowController;

Other than using a local variable as seen above, what workaround would you recommend in cases like these?

like image 246
LearnCocos2D Avatar asked Apr 02 '13 16:04

LearnCocos2D


1 Answers

When you declare a property as weak, you are promising that some other object takes care of ownership. That's what weak means. When you violate this, bad things happen. So, for example, when you write:

KTWindowController* windowController = [KTWindowController controller];
[self addSubController:windowController];
_windowController = windowController;

you're meeting your obligations: the strong temporary variable windowController handles ownership within this method, and then windowController subController handles ownership afterward.

When you wrote

 _windowController = [KTWindowController controller];

you weren't doing what you promised to do. _windowController is weak, so someone else is managing the lifetime. But -- look! No one is managing the lifetime! So we're free to get rid of the weak variable whenever we want to. The optimizer looks at this in your release build and says,

Hey! This guy says he doesn't care if this window controller lives or dies, as long as nobody else cares. Some people! But that's none of my business. But look at this: since he doesn't care, I don't have to make it at all! Or, at any rate, I can get rid of it the instant I make it.

The compiler is just doing what you said you wanted.

Are you sure you want this to be a weak property? Whenever I see this in my code, I make a point of checking that the property really should be weak; often, I want a strong property anyway.

like image 114
Mark Bernstein Avatar answered Sep 23 '22 19:09

Mark Bernstein