JHHK

欢迎来到我的个人网站
行者常至 为者常成

1、Singleton

目录

什么是单例模式

最简单,最常用的设计模式之一,主要解决了一个全局使用的类频繁地创建与销毁。
当您想控制实例数目,节省系统资源的时候,就可以使用单例模式

1、全局唯一,只初始化一次,只有一个实例
2、只提供一个接口,私有化初始化接口
3、线程安全
4、最好能懒加载(不强求)

单例模式实现

一、实现

class Singleton: NSObject {

    //存储类型属性在初始化时必须赋值,因为没有初始化器来初始化它,
    //存储类型属性的赋值是线程安全的,由系统 保证
    //let保证只赋值一次
    //存储类型属性默认lazy只有再使用时才会初始化
    //以上保证了可以实现单例模式
    static let shared = Singleton()
    
    //私有化初始化器
    private override init() {
        super.init()
    }
}

二、唯一性测试

func test1() {
    for _ in 0..<10 {
        let sle = Singleton.shared
        print(sle)
    }
    
    
    //调用初始化方法报错:Singleton' initializer is inaccessible due to 'private' protection level
    //let sle = Singleton()

    /**
    <LCClientDemo.Singleton: 0x281690090>
    <LCClientDemo.Singleton: 0x281690090>
    <LCClientDemo.Singleton: 0x281690090>
    <LCClientDemo.Singleton: 0x281690090>
    <LCClientDemo.Singleton: 0x281690090>
    <LCClientDemo.Singleton: 0x281690090>
    <LCClientDemo.Singleton: 0x281690090>
    <LCClientDemo.Singleton: 0x281690090>
    <LCClientDemo.Singleton: 0x281690090>
    <LCClientDemo.Singleton: 0x281690090>
    */
}

三、线程安全测试

func test2() {
    for _ in 0...10 {
        let thread = Thread.init {
            let sle = Singleton.shared
            print(Thread.current, sle)
        }
        thread.start()
    }
}

/**
<NSThread: 0x2801c0340>{number =  8, name = (null)} <LCClientDemo.Singleton: 0x281690090>
<NSThread: 0x2801c15c0>{number =  9, name = (null)} <LCClientDemo.Singleton: 0x281690090>
<NSThread: 0x2801c1c80>{number = 10, name = (null)} <LCClientDemo.Singleton: 0x281690090>
<NSThread: 0x2801c09c0>{number = 11, name = (null)} <LCClientDemo.Singleton: 0x281690090>
<NSThread: 0x2801c0000>{number = 12, name = (null)} <LCClientDemo.Singleton: 0x281690090>
<NSThread: 0x2801c2080>{number = 14, name = (null)} <LCClientDemo.Singleton: 0x281690090>
<NSThread: 0x2801c5880>{number = 17, name = (null)} <LCClientDemo.Singleton: 0x281690090>
<NSThread: 0x2801c7f40>{number = 18, name = (null)} <LCClientDemo.Singleton: 0x281690090>
<NSThread: 0x2801c0c80>{number = 13, name = (null)} <LCClientDemo.Singleton: 0x281690090>
<NSThread: 0x2801c0940>{number = 15, name = (null)} <LCClientDemo.Singleton: 0x281690090>
<NSThread: 0x2801c1680>{number = 16, name = (null)} <LCClientDemo.Singleton: 0x281690090>
*/

单例应用

1、程序整个生命周期内有且只有一份
UIApplication.shared

2、管理工具类
UserDefaults.standard
FileManager.default
NotificationCenter.default

补充

一、OC的实现方式

static LCLoginMananger * manager = nil;
+(instancetype)shareInstance{
    static dispatch_once_t onceToken;

    //保证线程安全和一次执行
    dispatch_once(&onceToken, ^{
        manager = [[LCLoginMananger alloc] init];
        manager.biometry = [[LCBiometryTool alloc] init];
        [manager copyBundleToUserDefault];
    });
    return manager;
}


//保证alloc和new出的也是同一对象
//+(instancetype)alloc{
//    if (!manager) {
//        manager = [super alloc];
//    }
//    return manager;
//}


//保证allocWithZone出的也是同一个对象
//alloc会调用allocWithZone,所以重写了这个方法,上边的方法可以不重写
+(instancetype)allocWithZone:(struct _NSZone *)zone{
    if (!manager){
        manager = [super allocWithZone:zone];
    }
    return manager;
}

二、调用

-(void)sharedTest{

    for (int i = 0; i<10; i++) {
        
        NSThread * thread = [[NSThread alloc] initWithBlock:^{
            LCLoginMananger * manger = [LCLoginMananger shareInstance];
            NSLog(@"manager = %@,thread = %@",manger,[NSThread currentThread]);
        }];
        
        [thread start];
    }
    
    
    LCLoginMananger * manager0 = [[LCLoginMananger alloc] init];
    NSLog(@"manager0 = %@",manager0);
    
    LCLoginMananger * manager1 = [LCLoginMananger new];
    NSLog(@"manager1 = %@",manager1);
    
    
    LCLoginMananger * manager2 = [[LCLoginMananger allocWithZone:nil] init];
    NSLog(@"manager2 = %@",manager2);
    
    /**
     manager0 = <LCLoginMananger: 0x2813f9a60>
     manager1 = <LCLoginMananger: 0x2813f9a60>
     manager2 = <LCLoginMananger: 0x2813f9a60>
     manager  = <LCLoginMananger: 0x2813f9a60>,thread = <NSThread: 0x28048d080>{number = 9, name = (null)}
     manager  = <LCLoginMananger: 0x2813f9a60>,thread = <NSThread: 0x28048d0c0>{number = 10, name = (null)}
     manager  = <LCLoginMananger: 0x2813f9a60>,thread = <NSThread: 0x28048cf40>{number = 11, name = (null)}
     manager  = <LCLoginMananger: 0x2813f9a60>,thread = <NSThread: 0x28048d040>{number = 12, name = (null)}
     manager  = <LCLoginMananger: 0x2813f9a60>,thread = <NSThread: 0x28048d000>{number = 13, name = (null)}
     manager  = <LCLoginMananger: 0x2813f9a60>,thread = <NSThread: 0x28048cf80>{number = 15, name = (null)}
     manager  = <LCLoginMananger: 0x2813f9a60>,thread = <NSThread: 0x28048cfc0>{number = 14, name = (null)}
     manager  = <LCLoginMananger: 0x2813f9a60>,thread = <NSThread: 0x28048ce40>{number = 16, name = (null)}
     manager  = <LCLoginMananger: 0x2813f9a60>,thread = <NSThread: 0x28048ce80>{number = 17, name = (null)}
     manager  = <LCLoginMananger: 0x2813f9a60>,thread = <NSThread: 0x28048d100>{number = 18, name = (null)}
     */
}

行者常至,为者常成!





R
Valine - A simple comment system based on Leancloud.