How to restrict the call to alloc,init in obj c singleton class

Refresh

March 2019

Views

862 time

1

I am creating a singleton class in obj c with the following Dispatch once block,

in ClassName.m

+ (instancetype)sharedInstance
{
    static ClassName*objClassName = nil;
    static dispatch_once_t onceToken = 0;

    dispatch_once(&onceToken, ^{
        objClassName = [[ClassName alloc]init];
    });

    return objClassName;
}

and I am using the following code in ClassName.h to not allow using alloc and init

- (id)init __attribute__((unavailable("You cannot init this class directly. Use sharedInstance to get the singleton Instance")));

+ (id)alloc __attribute__((unavailable("You cannot alloc this class directly. Use sharedInstance to get the singleton Instance")));

+ (id)new __attribute__((unavailable("You cannot use new this class directly. Use sharedInstance to get the singleton Instance")));

but it is not allowing my singleton method to use alloc init , please let me the where am I going wrong,

2 answers

2

Use UNAVAILABLE_ATTRIBUTE abolish init method, and implement initPrivate

+ (instancetype)shareInstance;

- (instancetype)init UNAVAILABLE_ATTRIBUTE;
+ (instancetype)new UNAVAILABLE_ATTRIBUTE;
implement

+ (instancetype)shareInstance {
    static MyClass *shareInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        shareInstance = [[super allocWithZone:NULL] initPrivate];
    });
    return shareInstance;
}

- (instancetype)initPrivate {
    self = [super init];
    if (self) {

    }
    return self;
}

//  MARK: Rewrite
+ (id)allocWithZone:(struct _NSZone *)zone {
    return [MyClass shareInstance];
}

- (id)copyWithZone:(NSZone *)zone
{
    return self;
}

From this post Singleton pattern in objc, how to keep init private?

0

Try the below answer

  +(id)share
  {
     static ClassName *final=nil;
     if(final==nil)
     {
       final=[[self alloc]init];
     }
     return final;
   }