What does the unavailable attribute in Objective C do?
__attribute__((unavailable("message")))
Is there any online reference to this and other attributes in Clang?
What does the unavailable attribute in Objective C do?
__attribute__((unavailable("message")))
Is there any online reference to this and other attributes in Clang?
The unavailable
attribute marks a function declaration so that you can generate an error message if someone tries to use it. It's essentially the same as the deprecated
attribute, except that trying to use a deprecated
function just causes a warning, but using an unavailable
one causes an error. Documentation at: http://clang.llvm.org/docs/LanguageExtensions.html
Here's a simple use case example. First the code:
void badFunction(void) __attribute__((unavailable("Don't use badFunction, it won't work.")));
int main(void)
{
badFunction();
return 0;
}
And then building it:
$ make example
cc example.c -o example
example.c:5:5: error: 'badFunction' is unavailable: Don't use badFunction, it
won't work.
badFunction();
^
example.c:1:6: note: function has been explicitly marked unavailable here
void badFunction(void) __attribute__((unavailable("Don't use...
^
1 error generated.
make: *** [example] Error 1
Without getting into a discussion of the pros and cons of singleton objects, attribute((unavailable("message"))) is handy for preventing singletons from being instantiated outside of the standard "sharedInstance" method.
For instance, in the header file of your singleton manager object the following lines will prevent the use of alloc, init, new or copy.
// clue for improper use (produces compile time error)
+ (instancetype)alloc __attribute__((unavailable("alloc not available, call sharedInstance instead")));
- (instancetype)init __attribute__((unavailable("init not available, call sharedInstance instead")));
+ (instancetype)new __attribute__((unavailable("new not available, call sharedInstance instead")));
- (instancetype)copy __attribute__((unavailable("copy not available, call sharedInstance instead")));
In order to instantiate your singleton you will need to roll your own custom initialization routine. Something along the lines of:
@interface singletonManager ()
-(instancetype)initUniqueInstance;
@end
@implementation singletonManager
+ (instancetype)sharedInstance
{
static id instance = nil;
static dispatch_once_t onceToken = 0;
dispatch_once(&once_token,^
{
instance = [[super alloc] initUniqueInstance];
});
return instance;
}
- (instancetype)initUniqueInstance
{
if (( self = [super init] ))
{
//regular initialization stuff
}
return self;
}
@end