Most likely, DEBUG builds cause the object to sit in the autorelease pool long enough to cause it to "work" whereas a RELEASE build causes the optimizer to do a bit more control flow analysis which subsequently eliminates the autorelease chatter.
Frankly, that the compiler isn't spewing a warning in the release build saying that the code can never work is a bug (please file it as you have a great, concise, example)!
You'll need to maintain a strong reference somewhere to the object until whatever needs a strong reference has an opportunity to take a reference.
I'm wondering if something like this might work:
- (NSObject *)theObject
{
NSObject *strongObject;
if (!_theObject) {
strongObject = [[NSObject alloc] init];
_theObject = strongObject;
// Perform further setup of _theObject...
} else {
strongObject = _theObject;
}
return strongObject;
}
I.e. the above would be more akin to a factory method that returns an autoreleased object while also maintaining a weak reference internally. But the optimizer might be too clever by half and break the above, too.