【iOS】—— 单例模式

1.单例模式的介绍:

单例模式是一种软件设计模式,旨在确保一个类只有一个实例,并提供全局访问点以获取该实例。它限制了类的实例化过程,以避免多个实例的创建,并提供一种方便的方式来访问该实例。

2.单例模式的优缺点:

单例模式的优点:

  • 单例模式提供了一个全局访问点,可以在应用程序的任何地方方便地访问单例实例,避免了传递实例引用的麻烦。
  • 单例模式适用于需要共享资源,确保所有使用该资源的代码都使用同一实例。

单例模式的缺点:

  • 单例实例一旦创建,对象指针是保存在静态区的,那么在堆区分配空间只有在应用程序终止后才会被释放。单例对象只要程序在运行中就会一直占用系统内存,该对象在闲置时并不能销毁,在闲置时也消耗了系统内存资源。
  • 单例不能被继承,不能有子类,因为它们共享一份资源,有子类单例模式就没有意义了。

3.单例模式的实现:

(1) 懒汉模式:

指在首次访问单例对象之前,并不会提前创建该对象。而是在第一次使用单例对象的时候才会进行创建和初始化。具体而言,当应用程序中的某个代码路径首次访问单例对象时,懒汉模式会检查该对象是否已经被创建。如果尚未创建,则会执行创建和初始化的操作,然后返回该单例实例的引用。这样可以避免在应用程序启动或加载时就创建单例对象,从而节省了系统资源。

#import "FKSinglenton"

static id _instance = nil;
@implementation FKSinglenton

+ (id) instance {
    //如果instance为nil
    if (!_instance) {
        //创建一个Singletion实例,并将该实例赋值给instance全局变量
        _instance = [[super alloc] init];
    }
    return _instance;
}
@end

上述形式创建单例模式会缺少线程安全性,多个线程可能会同时通过 + (id)instance 方法访问单例对象。这可能导致多个实例被创建,违反了单例的唯一性。
因此这里需要用到 dispatch_once 函数来确保只有一个线程能够执行实例创建代码块,从而保证了线程安全性。修改代码如下:

#import "Singlenton"

static id _instance = nil;

@implementation Singlenton
+ (instancetype)instance {
    static dispatch_once_t onceToken;
    //确保只有一个线程能够执行实例创建代码块,从而保证了线程安全性。
    dispatch_once(&onceToken, ^{
        _instance = [[self alloc] init];
    });
    return _instance;
}

#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import "Singleton.h"
int main(int argc, char * argv[]) {
    NSString * appDelegateClassName;
    @autoreleasepool {
        // Setup code that might create autoreleased objects goes here.
        appDelegateClassName = NSStringFromClass([AppDelegate class]);
        //判断两次获取的实例是否相等,程序返回1,(代表真)。
        NSLog(@"%d" ,[Singleton instance] == [Singleton instance]);
    }
    return UIApplicationMain(argc, argv, nil, appDelegateClassName);
}

运行的结果如下:
在这里插入图片描述

还有一种方式就是给代码加锁,也可以解决上述问题。

#import "Singleton.h"

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

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

运行结果如下:
在这里插入图片描述

(2) 饿汉模式:

饿汉模式在类加载时就创建了单例对象,并且在整个程序生命周期中都一直存在。这意味着无论是否使用到该单例对象,它都会在程序开始运行时被创建,而不是在首次使用时才创建。

+ (void)load{
    _instance = [[self alloc] init];
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone{
    if (_instance == nil) { // 防止创建多次
        _instance = [super allocWithZone:zone];
    }
    return _instance;
}

+ (id) instance {
    return _instance;
}

运行结果如下:
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值