Objective-C Singletons and LLVM/clang leak warnings - objective-c

I'm using the singleton pattern in several places in an application, and I'm getting memory leak errors from clang when analyzing the code.
static MyClass *_sharedMyClass;
+ (MyClass *)sharedMyClass {
#synchronized(self) {
if (_sharedMyClass == nil)
[[self alloc] init];
}
return _sharedMyClass;
}
// clang error: Object allocated on line 5 is no longer referenced after this point and has a retain count of +1 (object leaked)
I'm using these settings for scan-build:
scan-build -v -v -v -V -k xcodebuild
I'm fairly certain that the code in the singleton is just fine - after all, it's the same code referenced here on Stack Overflow as well as in Apple's documentation - but I would like to get the memory leak warning sorted out so my scan-build returns success.

I may be being exceptionally dense, but surely your line 5
[[self alloc] init];
allocates an object of the containing class type, and promptly throws it away? Do you not want
_sharedMyClass = [[self alloc] init];
?

Apple has since updated their recommended singleton code to pass the static analyzer:
+ (MyGizmoClass*)sharedManager
{
if (sharedGizmoManager == nil) {
sharedGizmoManager = [[super allocWithZone:NULL] init];
}
return sharedGizmoManager;
}
+ (id)allocWithZone:(NSZone *)zone
{
return [[self sharedManager] retain];
}
Now +sharedManager calls super's -allocWithZone: and assigns the return of -init, and the singleton's -allocWithZone: just returns a retained sharedInstance.
Edit:
Why the retain in +allocWithZone:?
+allocWithZone: is overridden because someone using MyGizmoClass could circumvent the singleton by calling [[MyGizmoClass alloc] init] instead of [MyGizmoClass sharedManager]. It's retained because +alloc is expected to always return an object with a retain count of +1.
Every call to +alloc should be balanced with a -release or -autorelease, so without the retain in +allocWithZone:, the shared instance could potentially be deallocated out from under other users.

You may be interested in a simple, one-method, GCD-based singleton implementation (and thus 10.6+ only) posted on Mike Ash's site:
+ (id)sharedFoo
{
static dispatch_once_t pred;
static Foo *foo = nil;
dispatch_once(&pred, ^{ foo = [[self alloc] init]; });
return foo;
}

You are referencing self in a class method! Big no-no! Secondly, you are calling [[self alloc] init] and just throwing away the instance. You should assign the singleton reference in the class method, and not in init like I am guessing you are doing. Next, there is no real guarantee that _sharedMyClass will be initialized to zero. You should explicitly initialize it to nil.
static MyClass *_sharedMyClass = nil;
+ (MyClass *)sharedMyClass {
#synchronized(self) {
if (_sharedMyClass == nil)
_sharedMyClass = [[MyClass alloc] init];
}
return _sharedMyClass;
}

You also probably had this in there too...
+ (id)allocWithZone:(NSZone *)zone {
#synchronized(self) {
if (sharedInstance == nil) {
sharedInstance = [super allocWithZone:zone];
return sharedInstance; // assignment and return on first allocation
}
}
return nil; // on subsequent allocation attempts return nil
}
The reason you weren't storing it in init is because you were storing it in the method that alloc called. This is the pattern Apple has in their examples. If you save the value in your init as well, all is fine and the warning goes away. I'd leave the allocWithZone implementation alone.

Related

Memory leak caused by alloc in Class Method?

I have found that if I alloc a new object inside a Class method and return it to main() it seems to cause a memory leak when I no longer want the object.
For example, here is a simple Class that includes a Class method that returns an instance of itself:
#interface Stinker : NSObject
{
int a;
}
+(instancetype) makeAStink;
-(void) showThem;
-(void) setEm: (int) z;
#end
#implementation Stinker
-(void) showThem
{
NSLog(#"%d",a);
}
-(void) setEm: (int) z
{
a = z;
}
-(void) dealloc
{
NSLog(#"Arrrgggggh!");
}
+(instancetype) makeAStink
{
id temp = [[self alloc] init];
return temp;
}
#end
Now if I create an instance directly from main():
Stinker *aStink =[[self alloc] init];
and subsequently set aStink to nil:
aStink = nil;
the overridden dealloc method is called and the Argggggh! message is logged. That's fine and as expected.
But if I use the Class method I wrote to create an instance:
Stinker *aNewStink = [Stinker makeAStink];
the behaviour is different.
Now if I set aNewStink to nil, it will no longer point to the object but the object is not destroyed. dealloc is not called and the Arggggh message is not logged.
It seems like it still has an owner somewhere.
Of course when main() terminates the object is destroyed and dealloc is eventually called.
But this seems to suggest that unused and unloved objects are still hanging around on the heap until the program terminates.
Isn't this a memory leak?
Should I just avoid using Class methods to alloc new instances?
When using ARC, the following code
+(instancetype) makeAStink
{
id temp = [[self alloc] init];
return temp;
}
will be same with Non-ARC like this:
+(instancetype) makeAStink
{
id temp = [[self alloc] init];
return [temp autorelease];
}
Thanks to autorelease, aNewStink = nil will make aNewStink do release in next runloop.
So if you do this:
#autoreleasepool {
Stinker *aNewStink = [Stinker makeAStink];
aNewStink = nil;
}
Dealloc method is called immediately.
this is MRC (without ARC) code for your example
+(instancetype) makeAStink
{
id temp = [[self alloc] init];
return [temp autorelease];
}
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
id obj = [Stinker makeAStink]; // obj is autoreleased object
id obj2 = [[Stinker alloc] init]; // obj2 is not autoreleased
[obj2 release]; // so you need to release it
[pool release]; // now obj is released and deallocated
so obj have an extra retain count which will be released (and deallocated) in next runloop whereas obj2 will be released immediately when release is called
this is not memory leak, it is usual behaviour and (normally) doesn't affect program performance in noticeable way

Objective C Constructer without init

When I'm creating custom classes, I'd like to be able to skip the alloc init part of the code once I go to construct an instance of the class. Similar to how it's done with:
NSString * ex = [NSString stringWithFormat...];
Basically I already have the class set up with a custom initializer method to set up my basic variables. However, when I'm on the front end and actually making these critters I have to say:
[[Monster alloc] initWithAttack:50 andDefense:45];
and I'd rather be able to say
[Monster monsterWithAttack:50 andDefense:45];
I know it's a simple stupid thing to just get rid of the alloc part but it makes the code more readable so I'd prefer to do it that way. I originally tried just changing my method from
-(id)initWithAttack:(int) a andDefense:(int) d
to
-(id)monsterWithAttack:(int) a andDefense:(int) d
and then changing my self = [super init] to self = [[super alloc] init]; but that clearly doesn't work! Any ideas?
You have to make a class method
+(id)monsterWithAttack:(int) a andDefense:(int) d
in which you create, initialize, and return an instance (and don't forget your memory management):
+(id)monsterWithAttack:(int) a andDefense:(int) d {
// Drop the autorelease IF you're using ARC
return [[[Monster alloc] initWithAttack:a andDefense:d] autorelease];
}
What you want is a convenience constructor. It's a class method that returns a useable instance of a class and allocates memory for it at the same time.
-(id)initWithAttack:(int)a andDefense:(int)d;
+(id)monsterWithAttack:(int)a andDefense:(int)d;
+(id)monsterWithAttack:(int)a andDefense:(int)d {
//-autorelease under MRC
return [[[self class] alloc] initWithAttack:a andDefense:d];
}
-(id)initWithAttack:(int)a andDefense:(int)d {
self = [super init];
if (self){
//custom initialization
}
return self;
}
You should use a class factory method in the header of monster class.
+(id)monsterWithAttack:(int) attackValue andDefense:(int) defenseValue
in the implementetation of monster class
+(id)monsterWithAttack:(int) attackValue andDefense:(int) defenseValue {
return [[[[self class] alloc] initWithAttack:attackValue andDefense:defenseValue] autorelease];
}
The use of [self class] guarantees the correct dispatch during subclassing. If you are using ARC you can avoid the autorelease method
Class methods of this type use autorelease.
So for instance, you might say:
+ (id)
monsterWithAttack:(int) a
defense:(int) d
{
return [[Monster alloc] initWithAttack:a defense:d]
autorelease];
}

Setting static inside its method call (with singleton pattern)

is smth. like this legit? it compiles and looks running ok, but is it ok? (aim setting myself to nil, inside my method)
i mean iam setting myself static to nil, in a method
static MyClass * StaticInstance = nil;
+ (MyClass *) sharedStaticInstance
{
if (StaticInstance == nil) {
StaticInstance = [[MyClass alloc] init];
}
return StaticInstance;
}
- (void) killStaticSelf
{
StaticInstance = nil;
}
and later
[[MyClass sharedStaticInstance] doSmth]; // our static instance is created
[[MyClass sharedStaticInstance] killStaticSelf]; // now its killed inside itself method
[[MyClass sharedStaticInstance] doSmth]; // now it should recreate again
Its having a memory leak.
You should dealloc the StaticInstance first and then you should assign nil to it.
Yes, that's how it's done. I use the sharedStaticInstance often, though I don't usually create a destructor it's probably a good idea, as long as all references to the shared instance in this class pass through sharedStaticInstance first.
EDIT: I just noticed that killStaticSelf is an instance method - it should be a class method I believe, but there shouldn't be any issue either way.
[MyClass killStaticSelf];
Even as the function stack closes, since sending messages to nil doesn't cause issues in Objective-C.
your sharedInstance method is not thread safe so you could get a race condition in this code:
if (StaticInstance == nil) {
StaticInstance = [[MyClass alloc] init];
}
- (void) killStaticSelf
{
StaticInstance = nil;
}
the above code has a leak since you do not provide StaticInstance as a retain property (apparently). You could instead wrap your singleton code in a property but that uses the same static instance.
It's legit, but you need to release the variable before setting it to nil, to avoid memory leaks if you're not using ARC.
Though comprehension of such singleton usage logic is beyond my humble brain abilities.

Singleton in iOS 5?

Hi I had an implementation previous versions of iOS for a singleton as follows:
.h file
#interface CartSingleton : NSObject
{
}
+(CartSingleton *) getSingleton;
.m file
#implementation CartSingleton
static CartSingleton *sharedSingleton = nil;
+(CartSingleton *) getSingleton
{
if (sharedSingleton !=nil)
{
NSLog(#"Cart has already been created.....");
return sharedSingleton;
}
#synchronized(self)
{
if (sharedSingleton == nil)
{
sharedSingleton = [[self alloc]init];
NSLog(#"Created a new Cart");
}
}
return sharedSingleton;
}
//==============================================================================
+(id)alloc
{
#synchronized([CartSingleton class])
{
NSLog(#"inside alloc");
NSAssert(sharedSingleton == nil, #"Attempted to allocate a second instance of a singleton.");
sharedSingleton = [super alloc];
return sharedSingleton;
}
return nil;
}
//==============================================================================
-(id)init
{
self = [super init];
}
However on the web I see people have implemented the Singleton design pattern using this code:
+ (id)sharedInstance
{
static dispatch_once_t pred = 0;
__strong static id _sharedObject = nil;
dispatch_once(&pred, ^{
_sharedObject = [[self alloc] init]; // or some other init method
});
return _sharedObject;
}
Could someone who is experience please guide me.
Im a newbie and thoroughly confused between the old iOS implementation of the Singleton and the new one and which is the correct one?
Thanks a lot
Strictly speaking, you must use:
+ (MySingleton*) instance {
static dispatch_once_t _singletonPredicate;
static MySingleton *_singleton = nil;
dispatch_once(&_singletonPredicate, ^{
_singleton = [[super allocWithZone:nil] init];
});
return _singleton;
}
+ (id) allocWithZone:(NSZone *)zone {
return [self instance];
}
Now you guarantee that one cannot call alloc/init and create another instance.
Explanation: The instance method is at the class level and is your main access method to get a reference to the singleton. The method simply uses the dispatch_once() built-in queue that will only execute a block once. How does the runtime guarantee that the block is only executed once? Using the predicate you supply (of type dispatch_once_t). This low-level call will guarantee that even if there are multiple threads trying to call it, only one succeeds, the others wait until the first one is done and then returns.
The reason we override allocWithZone is because alloc calls allocWithZone passing nil as the zone (for the default zone). To prevent rogue code from allocating and init-ializing another instance we override allocWithZone so that the instance passed back is the already initialized singleton. This prevents one from creating a second instance.
The dispatch_once snippet is functionally identical to other one. You can read about it at http://developer.apple.com/library/mac/#documentation/Darwin/Reference/Manpages/man3/dispatch_once.3.html.
This is what I use for singletons:
+ (MySingleton*) getOne {
static MySingleton* _one = nil;
#synchronized( self ) {
if( _one == nil ) {
_one = [[ MySingleton alloc ] init ];
}
}
return _one;
}
NOTE: In most cases, you do not even need to use #synchronized (but it is safe this way).
A singleton is a special kind of class where only one instance of the class exists for the current process. (In the case of an iPhone app, the one instance is shared across the entire app.) Some examples in UIKit are [UIApplication sharedApplication] (which returns the sole instance of the application itself), and [NSFileManager defaultManager] (which returns the file manager instance). Singletons can be an easy way to share data and common methods across your entire app.
Rather than create instances of the singleton class using alloc/init, you'll call a class method that will return the singleton object. You can name the class method anything, but common practice is to call it sharedName or defaultName.
Please check a link with best answer
:http://www.idev101.com/code/Objective-C/singletons.html

Objective-C Properties and Memory Management

Given the following property definition:
#property (nonatomic,retain) MyObject* foo;
does the following code cause a memory leak:
self.foo = [[MyObject alloc] init];
?
It looks like the alloc call increments the retain count on the object to 1, then the retain inside the property setter increases it to 1. But since the initial count is never decremented to 0, the object will stick around even when self is released. Is that analysis correct?
If so, it looks like I have two alternatives:
self.foo = [[[MyObject alloc] init] autorelease];
which is not recommended on the iPhone for performance reasons, or:
MyObject* x = [[MyObject alloc] init];
self.foo = x
[x release];
which is a bit cumbersome. Are there other alternatives?
Are there any alternatives?
No.
You are not going to be able write much of an iPhone application without using autorelease and the Cocoa Touch library uses them in many places. Understand what it's doing (adding the pointer to a list for removal on the next frame) and avoid using it in tight loops.
You can use class method on MyObject that does alloc/init/autorelease for you to clean it up.
+ (MyObject *)object {
return [[[MyObject alloc] init] autorelease];
}
self.foo = [MyObject object];
The easiest way to manage a retained property on the iPhone is the following (autorelease is not as bad as you think, at least for most uses):
-(id)init {
if (self = [super init]) {
self.someObject = [[[Object alloc] init] autorelease];
}
return self;
}
-(void)dealloc {
[someObject release];
[super dealloc];
}
The autorelease releases the reference to the floating instance which is assigned to self.object which retains its own reference, leaving you with the one reference you need (someObject). Then when the class is destroyed the only remaining reference is released, destroying the object.
As described in another answer, you can also create one or more "constructor" messages to create and autorelease the objects with optional parameters.
+(Object)object;
+(Object)objectWithCount:(int)count;
+(Object)objectFromFile:(NSString *)path;
One could define these as:
// No need to release o if fails because its already autoreleased
+(Object)objectFromFile:(NSString *)path {
Object *o = [[[Object alloc] init] autorelease];
if (![o loadFromFile:path]) {
return nil;
}
return o;
}
You are right, self.foo = [[MyObject alloc] init]; is leaking memory. Both alternatives are correct and can be used. Regarding the autorelease in such a statement: keep in mind that the object will released by the autorelease pool as soon as the current run loop ends, but it will most probably be retained a lot longer by self, so there is no issue with memory usage spikes here.