iOS单例的三种创建方式

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

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,841评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,874评论 25 708
  • 单例模式(SingletonPattern)一般被认为是最简单、最易理解的设计模式,也因为它的简洁易懂,是项目中最...
    成热了阅读 4,285评论 4 34
  • 1.单例模式概述 (1)引言 单例模式是应用最广的模式之一,也是23种设计模式中最基本的一个。本文旨在总结通过Ja...
    曹丰斌阅读 2,996评论 6 47
  • 你跟我说 你不要活了 流传的故事中有你的一把匕首 那是用来催人性命 你说你已死了千千万万回 只这一次你想乖乖顺顺 ...
    柳橙芝阅读 308评论 0 10