MRC

####import "XBSoundTool.h"

@implementation XBSoundTool
/**
 创建单例的步骤

 1. 定义一个全局的静态变量,用来记录“第一次”被实例化出来的对象

 2. 重写allocWithZone方法,此方法是为对象分配内存空间必须会被调用的一个方法!
    因此,在此方法中使用"dispatch_once",能够保证在多线程中,_instance也只能被“分配”一次空间

 3. 定义一个sharedXXX“类”方法,方便其他使用单例的对象调用此单例
    在此方法中,同样使用"dispatch_once",保证使用类方法调用的对象,只会被初始化一次!

 注释:如果不考虑copy & MRC,以上三个步骤即可!

 4. 如果要支持copy,则需要
 1> 遵守NSCopying协议
 2> 在copyWithZone方法中,直接返回_instance

 =========================================
 */
static XBSoundTool *_instance;

// 在实际给对象分配内存空间时,最终都会调用此方法!
+ (id)allocWithZone:(struct _NSZone *)zone
{
    // 类似的代码
    // 1> 如果是多条线程同时分配对象,不能保证唯一性,“非线程安全”
//    if (!_instance) {
//        _instance = [super allocWithZone:zone];
//    }
//    return _instance;

    // 2> 要保证线程安全,使用互斥锁,互斥锁的性能非常不好!
//    static int token = 0;
//    @synchronized(self) {
//        if (token == 0) {
//            _instance = [super allocWithZone:zone];
//            token = 1;
//        }
//
//        return _instance;
//    }

    // 在此方法中,只要返回唯一的对象就可以了
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        // 此处的代码可以保证在多线程中,只会被执行一次!
        _instance = [super allocWithZone:zone];
    });

    return _instance;
}

+ (instancetype)sharedSoundTool
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        // 1. MRC修改的第一点,增加autorelease
        _instance = [[[CZSoundTool alloc] init] autorelease];
    });

    return _instance;
}

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

#pragma mark - MRC需要重写的方法,目的就是覆盖系统默认的内存管理方法
// 默认引用计数加1
- (id)retain
{
    // 单例中不需要增加引用计数
    return self;
}

// 在MRC中,使用过autorelease分配的对象,延迟销毁,出了作用域之后,会被放到自动释放池中
// 只有“堆”中的对象,才需要放到自动释放池中!
- (id)autorelease
{
    // 单例中不需要延迟销毁
    return self;
}

// retainCount表示有多少个对象对当前对象进行强引用,系统底层的框架同样会引用
// 实际开发中,跟踪引用技术数值是毫无意义的事情!
- (NSUInteger)retainCount
{
    // 单例中不需要修改引用计数,返回最大的无符号整数
//    return 1;
    return UINT_MAX;
}

- (oneway void)release
{
    // 在单例中,啥也不用做!
}

#pragma mark - 对象初始化方法
// 单例对象只应该被初始化一次
- (instancetype)init
{
    self = [super init];
    if (self) {

    }
    return self;
}

#pragma mark - 成员方法
- (void)playSoundWithName:(NSString *)name
{
    NSLog(@"播放 %@", name);
}

@end

你可能感兴趣的:(MRC)