美文网首页
ios~单例模式:

ios~单例模式:

作者: 阳光下的叶子呵 | 来源:发表于2022-03-30 15:19 被阅读0次

在iOS OC中,一般我们都是用官方推荐的写法来写单例:GCD方式单例


单例:整个程序只创建一次,全局共用。

1.  ****单例的创建****
// SharedPerson.h 文件中
+ (instancetype)share;

// SharedPerson.m 文件中
static SharedPerson *_person; 
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
        static dispatch_once_t predicate;
        dispatch_once(&predicate, ^{
            _person = [super allocWithZone:zone];
        });
        return _person;  
} 

+ (instancetype)share {     
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            _person = [[self alloc]init];
        }); 
        return _person;
} 
- (id)copyWithZone:(NSZone *)zone { 
      return _person;
}
  1. 分析单例
    • static SharedPerson *_person: 利用static关键字来确保创建的单例对象_person只能在此类中可以访问到;将_person定义成全局变量为了确保其生命周期存在于整个程序中,期间不被销毁.
    • dispatch_once : 此函数确保_person对象在程序中只会创建一次,并且也保证了创建时的线程安全。
    • + (instancetype)share : 提供便捷的类方法来创建单例对象,强烈建议用此法创建对象。
    • + (instancetype)allocWithZone:(struct _NSZone *)zone : [SharedPerson alloc]分配对象内存时,实际会调此函数allocWithZone:(struct _NSZone *)zone,所以需要重写此方法来保证单例对象只会创建一次,而且是必须重写此方法,防止其他开发者直接用初始化方法来创建单例对象。
    • - (id)copyWithZone:(NSZone *)zone : 此函数来保证单例对象可以copy再得到一个一模一样的对象。
3、一般使用:
+ (instancetype)sharedInstance;
+ (instancetype)sharedInstance {
    static URLManager * ins = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        ins = [[URLManager alloc] init];
    });
    return ins;
}

URLManager* a = [URLManager sharedInstance];
接下来,可以用 a 这个单例来干很多事情了,看起来没有问题。在很多实际的项目中,很多人也的确是这么做的。

可是,谁能保证所有人都会使用 sharedInstance 方法来创建对象?而一旦有人用 alloc,new 等来创建对象,这就不是单例了。
例如:

    URLManager* a = [URLManager sharedInstance];
    URLManager* b = [[URLManager alloc] init];
    URLManager* c = [URLManager new];

查看 a、b、c :


截屏2022-03-30 14.59.30.png

可以看到,a、b、c 不是同一个对象,而所谓单例,就是不管我用何种方法创建对象,都必须是同一个
所以,单例模式,绝不是一个 sharedInstance 就够了。

解决方案 一
那么如何避免这种问题呢?我们知道:
在对象创建的时候,无论是 alloc 还是 new,都会调用到 allocWithZone: 方法;
使用拷贝创建对象时,会调用 copyWithZone:,mutableCopyWithZone:方法;
那么,重写这些方法,就可以让创建的对象唯一。

+ (instancetype)sharedInstance {
    static URLManager * ins = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        ins = [[super allocWithZone:nil] init];
    });
    return ins;
}

+(id)allocWithZone:(NSZone *)zone{
    return [self sharedInstance];
}
-(id)copyWithZone:(NSZone *)zone{
    return [[self class] sharedInstance];
}
-(id)mutableCopyWithZone:(NSZone *)zone{
    return [[self class] sharedInstance];
}

再运行,看一看a、b、c:


截屏2022-03-30 15.03.01.png

都是同一个对象!大功告成!

解决方案 二
此外,还有一种方法,就是直接禁用掉 alloc、new 、copy等方法:

+(instancetype) alloc __attribute__((unavailable("replace with 'sharedInstance'")));

+(instancetype) new __attribute__((unavailable("replace with 'sharedInstance'")));

-(instancetype) copy __attribute__((unavailable("replace with 'sharedInstance'")));

-(instancetype) mutableCopy __attribute__((unavailable("replace with 'sharedInstance'")));

如此,在调用这些方法时就会报错,提示使用 sharedInstance 方法:


截屏2022-03-30 15.04.45.png

以此,也可以达到单例模式的要求,始终只有一个对象。

相关文章

  • 单例

    iOS单例模式iOS之单例模式初探iOS单例详解

  • iOS 单例模式

    关于单例模式的详解,看完这几篇,就完全了然了。iOS 单例模式iOS中的单例模式iOS单例的写法

  • iOS 单例模式 or NSUserDefaults

    本文内容:iOS的单例模式NSUserDefaults的使用总结:iOS单例模式 and NSUserDefaul...

  • 单例模式 Singleton Pattern

    单例模式-菜鸟教程 iOS中的设计模式——单例(Singleton) iOS-单例模式写一次就够了 如何正确地写出...

  • 【设计模式】单例模式

    学习文章 iOS设计模式 - 单例 SwiftSingleton 原理图 说明 单例模式人人用过,严格的单例模式很...

  • iOS模式设计之--创建型:1、单例模式

    iOS模式设计之--1、单例模式

  • iOS单例模式容错处理

    ios 单例模式容错处理 1、单例模式的使用和问题解决 在ios开发的过程中,使用单例模式的场景非常多。系统也有很...

  • 谈一谈iOS单例模式

    这篇文章主要和大家谈一谈iOS中的单例模式,单例模式是一种常用的软件设计模式,想要深入了解iOS单例模式的朋友可以...

  • iOS知识梳理3:设计模式

    iOS有哪些常见的设计模式?单例模式/委托模式/观察者模式/MVC模式 单例模式 单例保证了应用程序的生命周期内仅...

  • 单例对象

    iOS单例模式(Singleton)单例模式的意思就是:只有一个实例;单例模式确保每个类只有一个实例,而且自行实例...

网友评论

      本文标题:ios~单例模式:

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