iOS单例的三种创建方式

iOS单例的三种创建方式_第1张图片
head.jpg

INTRO:iOS中有很多单例的应用,单例模式就是确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。单例在工程运行时一直存在,因此它不是在堆区(随着对象的),而是在静态区
在ARC模式下,常用的两种创建方式:

1、GCD方式创建单例
static id _instance;
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
   static dispatch_once_t onceToken;
   dispatch_once(&onceToken, ^{
     _instance = [super allocWithZone:zone];
   });
 return _instance;
}
+ (instancetype)sharedInstance
{
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    _instance = [[self alloc] init];
  });
  return _instance;
}
- (id)copyWithZone:(NSZone *)zone
{
  return _instance;
}
- (id)mutableCopyWithZone:(NSZone *)zone {
  return _instance;
}
2、互斥锁方式
static id _instance;
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
  @synchronized(self) {
    if (_instance == nil) {
      _instance = [super allocWithZone:zone];
    }
  }
  return _instance;
}
+ (instancetype)sharedInstance
{
  @synchronized(self) {
    if (_instance == nil) {
      _instance = [[self alloc] init];
    }
  }
  return _instance;
}
- (id)copyWithZone:(NSZone *)zone
{
  return _instance;
}

在实际开发中,我们可以使用宏定义更方便的使用

// .h文件
#define JJSingletonH(name) + (instancetype)shared##name;

// .m文件
#if __has_feature(objc_arc)

#define JJSingletonM(name) \
static id _instace; \
\
+ (id)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instace = [super allocWithZone:zone]; \
}); \
return _instace; \
} \
\
+ (instancetype)shared##name \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instace = [[self alloc] init]; \
}); \
return _instace; \
} \
\
- (id)copyWithZone:(NSZone *)zone \
{ \
return _instace; \
}

#else

#define JJSingletonM(name) \
static id _instace; \
\
+ (id)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instace = [super allocWithZone:zone]; \
}); \
return _instace; \
} \
\
+ (instancetype)shared##name \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instace = [[self alloc] init]; \
}); \
return _instace; \
} \
\
- (id)copyWithZone:(NSZone *)zone \
{ \
return _instace; \
} \
\
- (oneway void)release { } \
- (id)retain { return self; } \
- (NSUInteger)retainCount { return 1;} \
- (id)autorelease { return self;}

#endif

最后,因为单例在整个运行的过程中都会一直存在,对内存消耗是比较大的,在使用时需要好好考虑.

你可能感兴趣的:(iOS单例的三种创建方式)