美文网首页iOS Developer
iOS中单例模式的两种实现方式

iOS中单例模式的两种实现方式

作者: NotFunGuy | 来源:发表于2017-06-27 16:13 被阅读119次

单例模式的作用

  • 可以保证程序运行过程中,一个类只有一个实例,而且该实例易于供外界访问
  • 节约系统资源

单例模式使用场合

  • 在整个应用程序中,共享一份资源(这份资源只需要创建和初始化一次

实现单例模式的方式

iOS中有两种实现单例模式的方式,一种是使用GCD,一种是不使用GCD

使用GCD实现单例模式代码

  • .h文件
#import <Foundation/Foundation.h>

@interface LMHPerson : NSObject

//单例方法
+(instancetype)sharedPerson;

@end
  • .m文件
#import "LMHPerson.h"

static LMHPerson * _person; // 单例(全局变量)

@implementation LMHPerson

/**
 * 单例方法
 */
+(instancetype)sharedPerson{
    
    // 确保只进行一次
    static dispatch_once_t onceToken;
    
    dispatch_once(&onceToken, ^{
        _person = [[self alloc]init];
    });
    
    return _person;
}

// alloc 会调用allocWithZone方法
+(instancetype)allocWithZone:(struct _NSZone *)zone{
    
    // 确保只进行一次
    static dispatch_once_t onceToken;
    
    dispatch_once(&onceToken, ^{
        _person = [super allocWithZone:zone];
    });
    
    return _person;
}

//copy在底层 会调用copyWithZone方法
+ (id)copyWithZone:(NSZone *)zone{
    
    return _person;
}
  • 测试&打印
    LMHPerson * person1 = [[LMHPerson alloc]init];
    LMHPerson * person2 = [LMHPerson sharedPerson];
    
    NSLog(@"%p %p", person1, person2);


可以看到,两个对象的内存地址都是一样的

不使用GCD实现单例模式代码

  • .h文件
#import <Foundation/Foundation.h>

@interface LMHCat : NSObject

// 单例方法
+(instancetype)sharedCat;

@end

  • .m文件
#import "LMHCat.h"

static LMHCat *_cat; // 单利(全局变量)

@implementation LMHCat

/**
 * 单例方法
 */
+(instancetype)sharedCat{
    
    @synchronized (self) { // 确保多线程情况下,仍然确保实体的唯一性
        if (!_cat) {
            _cat = [[LMHCat alloc]init];
        }
    }
    return _cat;
}

// alloc 会调用allocWithZone方法
+(instancetype)allocWithZone:(struct _NSZone *)zone{
    
    @synchronized (self) {
        if (!_cat) {
            _cat = [super allocWithZone:zone]; // 确保使用同一块内存地址
            
            return _cat;
        }
        
    }
    
    return nil;
}

//copy在底层 会调用copyWithZone方法
+ (id)copyWithZone:(NSZone *)zone{
    
    return _cat;
}
  • 测试&打印
    LMHCat * cat1 = [[LMHCat alloc]init];
    LMHCat * cat2 = [LMHCat sharedCat];
    
    NSLog(@"%p %p", cat1, cat2);


在不使用CGD实现单例模式的时候,用到了synchronized(互斥锁),用来确保线程安全,确保对象得唯一性,封锁用户通过alloc和init以及copy来构造对象的路劲。

相关文章

网友评论

    本文标题:iOS中单例模式的两种实现方式

    本文链接:https://www.haomeiwen.com/subject/hqyqxxtx.html