【iOS】—— 单例模式

一.单例模式的简单介绍:

单例模式是比较常见的一种设计模式,目的是保证一个类在运行期间有且只有一个实例,而且自行实例化并向整个系统提供这个实例,一直保存在内存中,到程序退出时由系统自动释放这部分内存。是避免频繁创造对象,节约内存的一种模式。

二.单例模式的优缺点:

单例模式的优点:

  • 单例可以保证系统中该类有且只有一个实例,所以很便于外界访问,对于项目中个别场景的传值,存储状态等更加方便。如果程序中出了问题,可以快速的定位问题所在。
  • 由于在整个程序中只存在一个对象,节省了系统内存资源,提高了程序的运行效率。

单例模式的缺点:

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

三.单例模式的实现:

单例模式又可以分为两种模式:

  • 懒汉模式:第一次用到单例对象的时候再创建。
  • 饿汉模式:一进入程序就创建一个单例对象。(不常用)

懒汉模式:

#import <Foundation/Foundation.h>

@interface Singleton : NSObject<NSMutableCopying, NSCopying>

//获取单例
+ (instancetype)sharedSingleton;

@end

//---------------------------------------------

#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)sharedSingleton {
    if (_instance == nil) { // 防止频繁加锁
        @synchronized(self) {
            if (_instance == nil) { // 防止创建多次
                _instance = [[self alloc] init];
            }
        }
    }
    return _instance;
}

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

- (id)mutableCopyWithZone:(NSZone *)zone {
    return _instance;
}
@end

@synchronized的作用是创建一个互斥锁,保证此时没有其它线程对self对象进行修改,保证代码的安全性。也就是包装这段代码是原子性的,安全的。这个是objective-c的一个锁定令牌,防止self对象在同一时间内被其他线程访问,起到保护线程安全的作用。

饿汉模式:

#import <Foundation/Foundation.h>

@interface Singleton : NSObject<NSMutableCopying, NSCopying>

//获取单例
+ (instancetype)sharedSingleton;

@end

//---------------------------------------------

#import "Singleton.h"

@implementation Singleton

static id _instance;

//当类加载到OC运行时环境中(内存),就会调用一次(一个类只会加载1次)
+ (void)load{
    _instance = [[self alloc] init];
}

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

+ (instancetype)sharedSingleton{
    return _instance;
}

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

- (id)mutableCopyWithZone:(NSZone *)zone {
    return _instance;
}
@end

static补充:

static关键字修饰局部变量:

  • 当static关键字修饰局部变量时,只会初始化一次且在程序中只有一份内存;
  • 关键字static不可以改变局部变量的作用域,但可延长局部变量的生命周期(直到程序结束才销毁)。

static关键字修饰全局变量:

  • 当static关键字修饰全局变量时,作用域仅限于当前文件,外部类是不可以访问到该全局变量的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值