I have a class that creates an object lazily and stores it as a weak property. Other classes may request this object, but must obviously keep a strong reference to it to keep the object from being deallocated:
// .h
@interface ObjectManager
@property(nonatomic, weak, readonly) NSObject *theObject;
@end
// .m
@interface ObjectManager ()
@property(nonatomic, weak, readwrite) NSObject *theObject;
@end
@implementation ObjectManager
- (NSObject *)theObject
{
if (!_theObject) {
_theObject = [[NSObject alloc] init];
// Perform further setup of _theObject...
}
return _theObject;
}
@end
When the scheme is Xcode is set to build for Debug, things work just fine - an object can call objectManagerInstance.theObject
and get back theObject
.
When the scheme is set to build for Release, theObject
returns nil
:
// Build for Debug:
NSObject *object = objectManagerInstance.theObject;
// object is now pointing to theObject.
// Build for Release:
NSObject *object = objectManagerInstance.theObject;
// object is now `nil`.
My guess is that the compiler is optimising my code by seeing that _theObject
is not used further in the accessor method itself, so the weak variable is being set to nil
before returning. It seems that I would have to create a strong reference before actually returning the variable, which I can only think to do using a block, but would be messy and I'd rather avoid it!
Is there some kind of keyword I can use with the return type to stop the ivar from being nilled so soon?
weak
? SinceObjectManager
creates the object and should hang onto it so others can access it, it should be astrong
property. – PuceObjectManager
serves a group of unrelated objects (it is a singleton class), andanObject
is not always needed. I am trying to keep to a lazy design pattern and not keepanObject
around when it is not needed. A weak property seemed like a convenient solution until I encountered this issue. – CandlelighttheObject
create and return an object. If your goal is to keep it around once it has been lazy loaded then it must be kept in astrong
ivar. – PucetheObject
is required by 2 other objects simultaneously, it must be the same instance oftheObject
. Do you know how I can keep the lazy loading but also ensure the object is deallocated when not needed? A form of manual reference counting might be possible, but messy. I accept that what I am trying to do is not 'best practice' - after alltheObject
isn't actually owned by anything. Resigning to this fact means I will lose out on a bit of optimisation in my code, which is a pain, but I might be able to live with it (begrudgingly). – Candlelight