单例

简介

单例模式:

  1. 永远只分配一块内存来创建对象
  2. 提供一个类方法, 返回内部唯一的一个对象(一个实例)
  3. 最好保证init方法也只初始化一次

ARC模式

ARC模式下的单例主要涉及以下几个方法:

// 重写的方法
+ (id)allocWithZone:(struct _NSZone *)zone;
- (id)init;
+ (id)copyWithZone:(struct _NSZone *)zone;
// 自定义的类方法
+ (instancetype)sharedAudioTool;

详细代码:

// 静态变量
static id _instance;

+ (id)allocWithZone:(struct _NSZone *)zone
{
    // 里面的代码永远只执行1次
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [super allocWithZone:zone];
    });

    // 返回对象
    return _instance;
}

- (id)init
{
    if (self = [super init]) {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            // 加载资源

        });
    }
    return self;
}

+ (id)copyWithZone:(struct _NSZone *)zone
{
    return _instance;
}

+ (instancetype)sharedAudioTool
{
    // 里面的代码永远只执行1次
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [[self alloc] init];
    });

    // 返回对象
    return _instance;
}

MRC模式

MRC模式下对比ARC要多重写几个方法,主要是屏蔽对单例对象引用计数操作的相关方法:

- (oneway void)release ; - (id)autorelease ; - (id)retain; - (NSUInteger)retainCount;

详细代码:

// oneway表示分布式对象
- (oneway void)release {

}

- (id)autorelease {
    return _instance;
}

- (id)retain {
    return _instance;
}

- (NSUInteger)retainCount {
    return 1;
}

兼容ARC和MRC

是否为ARC可以通过以下宏来判断:

__has_feature(objc_arc)

可以利用这个宏来判断采用ARC单例还是MRC单例:

#if __has_feature(objc_arc) 
// ARC单例
#else
// MRC单例
#endif

由于-init方法中有类的资源初始化,所以除了-init方法以外,其余方法都可以写入宏中。
详细定义的宏:

// ## : 连接字符串和参数
#define singleton_h(name) + (instancetype)shared##name;

#if __has_feature(objc_arc) // ARC

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

#else // 非ARC

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

#endif

然后通过在.h文件中写入代码:

singleton_h(AudioTool)

在.m文件中写入代码:

singleton_m(AudioTool)

就可以使用类方法sharedAudioTool创建单例。

你可能感兴趣的:(单例)