-
Notifications
You must be signed in to change notification settings - Fork 81
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Slight modifications to the .m file to avoid compile errors with latest clang compiler related to volatile #2
Comments
I'm having this same issue. Any updates on a fix? |
With the latest Xcode 4.2 release a new little bug is spotted by the compiler. I have managed to get it to compile by casting to (id) the problematic returned reference, but it is not completely warning free so I do not know how safe it is. In single threaded applications you have nothing to fear, but in multithreaded applications you have to be able to use your Singletons without any worry. The code you see above is mostly the one I am using now, except for: 1.) github wrote @EnD instead of @EnD for some reason. @synchronized(self) to @synchronized(self) |
With the latest Xcode 4.2 release a new little bug is spotted by the compiler. I have managed to get it to compile by casting to (id) the problematic returned reference, but it is not completely warning free so I do not know how safe it is. In single threaded applications you have nothing to fear, but in multithreaded applications you have to be able to use your Singletons without any worry. The code you see above is mostly the one I am using now, except for: 1.) github wrote @EnD instead of @EnD for some reason. @synchronized(self) to @synchronized(self) |
1 similar comment
With the latest Xcode 4.2 release a new little bug is spotted by the compiler. I have managed to get it to compile by casting to (id) the problematic returned reference, but it is not completely warning free so I do not know how safe it is. In single threaded applications you have nothing to fear, but in multithreaded applications you have to be able to use your Singletons without any worry. The code you see above is mostly the one I am using now, except for: 1.) github wrote @EnD instead of @EnD for some reason. @synchronized(self) to @synchronized(self) |
Any news about this issue? When this fix will be integrated in the master branch? |
Any update on this issue? warning: casting 'volatile MySingleton *' to type 'MySingleton *' discards qualifiers [-Wincompatible-pointer-types] |
In order not to have Clang's compiler (LLVM clang not LLVM-GCC) complain about this singleton utility in its latest releases (Xcode 4.1 and Xcode 4.2), I have to make some small changes to the source code:
(I had to add volatile to many instances in which a reference to the singleton object was returned)
//
// SynthesizeSingleton.h
//
// Modified by Karl Stenerud starting 16/04/2010.
// - Moved the swizzle code to allocWithZone so that non-default init methods may be
// used to initialize the singleton.
// - Added "lesser" singleton which allows other instances besides sharedInstance to be created.
// - Added guard ifndef so that this file can be used in multiple library distributions.
// - Made singleton variable name class-specific so that it can be used on multiple classes
// within the same compilation module.
//
// Modified by CJ Hanson on 26/02/2010.
// This version of Matt's code uses method_setImplementaiton() to dynamically
// replace the +sharedInstance method with one that does not use @synchronized
//
// Based on code by Matt Gallagher from CocoaWithLove
//
// Created by Matt Gallagher on 20/10/08.
// Copyright 2009 Matt Gallagher. All rights reserved.
//
// Permission is given to use this source code file without charge in any
// project, commercial or otherwise, entirely at your risk, with the condition
// that any redistribution (in part or whole) of source code must retain
// this copyright and permission notice. Attribution in compiled projects is
// appreciated but not required.
//
ifndef SYNTHESIZE_SINGLETON_FOR_CLASS
import <objc/runtime.h>
pragma mark -
pragma mark Singleton
/* Synthesize Singleton For Class
*
*
*
*
*
*
*
*
*
*
*
*/
define SYNTHESIZE_SINGLETON_FOR_CLASS_HEADER(SS_CLASSNAME) \
\
define SYNTHESIZE_SINGLETON_FOR_CLASS_PROTOTYPE(SS_CLASSNAME) \
@interface SS_CLASSNAME (SynthesizeSingletonPrivate) \
@EnD
define SYNTHESIZE_SINGLETON_FOR_CLASS(SS_CLASSNAME) \
static volatile SS_CLASSNAME* _##SS_CLASSNAME##_sharedInstance = nil;
\
{
return (volatile SS_CLASSNAME_) _##SS_CLASSNAME##_sharedInstance;
}
\
{
@synchronized(self)
{
if(nil == _##SS_CLASSNAME##_sharedInstance)
{
_##SS_CLASSNAME##sharedInstance = [[self alloc] init];
}
}
return (volatile SS_CLASSNAME) _##SS_CLASSNAME##_sharedInstance;
}
\
{
return (volatile SS_CLASSNAME_)[self sharedInstanceSynch];
}
\
{
@synchronized(self)
{
if (nil == _##SS_CLASSNAME##_sharedInstance)
{
_##SS_CLASSNAME##_sharedInstance = [super allocWithZone:zone];
if(nil != _##SS_CLASSNAME##_sharedInstance)
{
Method newSharedInstanceMethod = class_getClassMethod(self, @selector(sharedInstanceNoSynch));
method_setImplementation(class_getClassMethod(self, @selector(sharedInstance)), method_getImplementation(newSharedInstanceMethod));
method_setImplementation(class_getInstanceMethod(self, @selector(retainCount)), class_getMethodImplementation(self, @selector(retainCountDoNothing)));
method_setImplementation(class_getInstanceMethod(self, @selector(release)), class_getMethodImplementation(self, @selector(releaseDoNothing)));
method_setImplementation(class_getInstanceMethod(self, @selector(autorelease)), class_getMethodImplementation(self, @selector(autoreleaseDoNothing)));
}
}
}
return _##SS_CLASSNAME##_sharedInstance;
}
\
{
@synchronized(self)
{
if(nil != _##SS_CLASSNAME##sharedInstance)
{
Method newSharedInstanceMethod = class_getClassMethod(self, @selector(sharedInstanceSynch));
method_setImplementation(class_getClassMethod(self, @selector(sharedInstance)), method_getImplementation(newSharedInstanceMethod));
method_setImplementation(class_getInstanceMethod(self, @selector(retainCount)), class_getMethodImplementation(self, @selector(retainCountDoSomething)));
method_setImplementation(class_getInstanceMethod(self, @selector(release)), class_getMethodImplementation(self, @selector(releaseDoSomething)));
method_setImplementation(class_getInstanceMethod(self, @selector(autorelease)), class_getMethodImplementation(self, @selector(autoreleaseDoSomething)));
[##SS_CLASSNAME##_sharedInstance release];
_##SS_CLASSNAME##_sharedInstance = nil;
}
}
}
\
{
return self;
}
\
{
return self;
}
\
{
NSAssert1(1==0, @"SynthesizeSingleton: %@ ERROR: -(NSUInteger)retainCount method did not get swizzled.", self);
return NSUIntegerMax;
}
\
{
return NSUIntegerMax;
} \
{
return [super retainCount];
}
\
{
NSAssert1(1==0, @"SynthesizeSingleton: %@ ERROR: -(void)release method did not get swizzled.", self);
}
\
\
{
@synchronized(self)
{
[super release];
}
}
\
{
NSAssert1(1==0, @"SynthesizeSingleton: %@ ERROR: -(id)autorelease method did not get swizzled.", self);
return self;
}
\
{
return self;
}
\
{
return [super autorelease];
}
pragma mark -
pragma mark Lesser Singleton
/* A lesser singleton has a shared instance, but can also be instantiated on its own.
*
*
*
*
*
*
*
*
*
*/
define SYNTHESIZE_LESSER_SINGLETON_FOR_CLASS(SS_CLASSNAME) \
static volatile SS_CLASSNAME* _##SS_CLASSNAME##_sharedInstance = nil;
\
{
return (SS_CLASSNAME_) _##SS_CLASSNAME##_sharedInstance;
}
\
{
@synchronized(self)
{
if(nil == _##SS_CLASSNAME##_sharedInstance)
{
_##SS_CLASSNAME##sharedInstance = [[self alloc] init];
if(##SS_CLASSNAME##sharedInstance)
{
Method newSharedInstanceMethod = class_getClassMethod(self, @selector(sharedInstanceNoSynch));
method_setImplementation(class_getClassMethod(self, @selector(sharedInstance)), method_getImplementation(newSharedInstanceMethod));
}
}
}
return (SS_CLASSNAME) _##SS_CLASSNAME##_sharedInstance;
}
\
{
return (volatile SS_CLASSNAME_) [self sharedInstanceSynch];
}
\
{
@synchronized(self)
{
Method newSharedInstanceMethod = class_getClassMethod(self, @selector(sharedInstanceSynch));
method_setImplementation(class_getClassMethod(self, @selector(sharedInstance)), method_getImplementation(newSharedInstanceMethod));
[_##SS_CLASSNAME##_sharedInstance release];
_##SS_CLASSNAME##_sharedInstance = nil;
}
}
define CALL_LESSER_SINGLETON_INIT_METHOD_PRE(SS_CLASSNAME) \
@synchronized(self)
{
if(nil == _##SS_CLASSNAME##_sharedInstance)
{
define CALL_LESSER_SINGLETON_INIT_METHOD_POST(SS_CLASSNAME) \
if(_##SS_CLASSNAME##_sharedInstance)
{
Method newSharedInstanceMethod = class_getClassMethod(self, @selector(sharedInstanceNoSynch));
method_setImplementation(class_getClassMethod(self, @selector(sharedInstance)), method_getImplementation(newSharedInstanceMethod));
}
}
}
define CALL_LESSER_SINGLETON_INIT_METHOD(SS_CLASSNAME,INIT_CALL) \
CALL_LESSER_SINGLETON_INIT_METHOD_PRE(SS_CLASSNAME);
_##SS_CLASSNAME##_sharedInstance = [[self alloc] INIT_CALL];
CALL_LESSER_SINGLETON_INIT_METHOD_POST(SS_CLASSNAME)
endif /* SYNTHESIZE_SINGLETON_FOR_CLASS */
The text was updated successfully, but these errors were encountered: