ios-单例模式饿汉式&GCD&懒汉式&宏方式的实现和条件编译

本文详细介绍了iOS开发中单例模式的实现方法,包括饿汉式、懒汉式及GCD实现方式,并提供了非ARC环境下的实现代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

饿汉式其实就是当程序一启动就是创建单例,在ios中不推荐去使用

static id instance;
+ (void)load //装载内存时就实例化,仅此一次
{
    _instance = [[self alloc] init];
}
+ (id)allocWithZone:(struct _NSZone *)zone
{     
    //这里可以不用加锁,因为是在load里面创建的
    if (_instance == nil) { // 防止创建多次
        _instance = [super allocWithZone:zone];
    }
    return _instance;
}
+ (instancetype)sharedManagerTool
{
    return _instance;
}
- (id)copyWithZone:(NSZone *)zone
{
    return _instance;
}
GCD的单例实现方式

static id _instace;

+ (id)allocWithZone:(struct _NSZone *)zone
{
    static dispatch_once_t onceToken;
    //这个函数是线程安全的
    dispatch_once(&onceToken, ^{
        _instace = [super allocWithZone:zone];
    });
    return _instace;
}

+ (instancetype)sharedDataTool
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instace = [[self alloc] init];
    });
    return _instace;
}

- (id)copyWithZone:(NSZone *)zone
{
    return _instace;
}
懒汉式的实现就是在用到的时候再去创建

static id _instance;
//alloc内部会调用这个代码
+ (id)allocWithZone:(struct _NSZone *)zone
{
    if (_instance == nil) { // 防止频繁加锁
        @synchronized(self) {
            if (_instance == nil) { // 防止创建多次
                _instance = [super allocWithZone:zone];
            }
        }
    }
    return _instance;
}

+ (instancetype)sharedMusicTool
{
    if (_instance == nil) { // 防止频繁加锁
        @synchronized(self) {
            if (_instance == nil) { // 防止创建多次
                _instance = [[self alloc] init];
            }
        }
    }
    return _instance;
}

- (id)copyWithZone:(NSZone *)zone
{
    return _instance;
}
非ARC下的单例模式

static id _instace;

+ (id)allocWithZone:(struct _NSZone *)zone
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instace = [super allocWithZone:zone];
    });
    return _instace;
}

+ (instancetype)sharedDataTool
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instace = [[self alloc] init];
    });
    return _instace;
}

- (id)copyWithZone:(NSZone *)zone
{
    return _instace;
}
//为了保证对象不被释放,所以在release中不做任何操作
-(oneway void)release
{
}
//retain的时候返回自己
- (id)retain
{
    return self;
}
- (NSUInteger)retainCount
{
    return 1;
}
//这里其实加不加都一样,因为最后会调用release操作,而我们又重写了release方法
- (id)autorelease {
    
    return self;
}
因为我们如果每用到一个类就要去复制这些代码,所以我们可以把这些代码定义成宏,确定就是不好调试。\这个的意思就是后面的一行都是它的.我们想用的话想把sharedInstance的Instance的名字改成我们自己传的名字,下面加()和传入参数name

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

// .m文件
#define SingletonM(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:(NSZone *)zone \
{ \
    return _instance; \
}

我们在写项目的时候如果想要指定在ARC下执行什么代码,在MRC下执行什么代码,我们可以用条件编译来写

#if __has_feature(objc_arc)
    //编译环境是ARC
    NSLog(@"kkk");
#else
    //编译环境是MRC
    NSLog(@"kkk");
#endif




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值