IOS 单例模式笔记

这里不讲单例模式的用途了,下面的代码,主要都会在.m文件的代码。
多线程

#import "SingletonClass.h"

@implementation SingletonClass

+ (SingletonClass *)shareSingletonClass {
    SingletonClass* singleton = [[SingletonClass alloc] init];
    return singleton;
}

@end

这里定义了一个类方法shareSingletonClass,这个单例类会调用这个方法获得全局惟一实例,但显然如今还达不到生成全局惟一实例的效果,每次调用这个方法都会生成一个新的实例。并发

再次修改:
高并发

#import "SingletonClass.h"

static SingletonClass* singleton = nil;

@implementation SingletonClass

+ (SingletonClass *)shareSingletonClass {
    
    if (singleton == nil) {
        singleton = [[SingletonClass alloc] init];
    }
    
    return singleton;
}

@end

这里生成了一个静态的SingletonClass实例,而后判断若是这个实例没有被建立,就建立,不然直接返回这个实例。
性能

但这种作法只适合单线程,多线程的状况下,各个线程在最开始都会判断到singleton=nil,会生成多个singleton实例。因此这时候须要线程锁:优化

+ (SingletonClass *)shareSingletonClass {
    
    @synchronized(self) {
        if (singleton == nil) {
            singleton = [[SingletonClass alloc] init];
        }
    }
    
    return singleton;
}

这样子已经完成一个单例了。
spa

可是在有高并发线程的状况下,每次都要作if判断,是很耗性能的,在线程锁里面的代码,是越少越好,而咱们真正所须要的是singleton = [[SingletonClass alloc] init];这句代码,因此能够把线程锁移到if判断里面。线程

+ (SingletonClass *)shareSingletonClass
{
    
    if (singleton == nil) {
        @synchronized(self) {
            singleton = [[SingletonClass alloc] init];
        }
    }
    
    return singleton;
}

但这样在多线程下,新线程仍是会近到线程锁里面,生成新的实例,因此仍是要再作一层判断:
code

+ (SingletonClass *)shareSingletonClass
{
    
    if (singleton == nil) {
        @synchronized(self) {
            if (singleton == nil) {
                singleton = [[SingletonClass alloc] init];
            }
        }
    }
    
    return singleton;
}

第一个if判断,使得只有在实例没被建立后,才会进到线程锁里面,减小进入线程锁判断;第二个判断,是多线程的时候的判断,进到这里的概率已经少了不少了。这种是多层线程锁。
it


事实上,在OBJC里面,对于单例,已经为咱们准备好了方法:io

+ (SingletonClass *)shareSingletonClass
{
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        singleton = [[SingletonClass alloc] init];
    });
    
    return singleton;
}

系统的方法,通常是被优化到最佳的,因此推荐使用这种方法。

相关文章
相关标签/搜索