美文网首页
单例全局唯一性

单例全局唯一性

作者: Ever_Blacks | 来源:发表于2016-05-19 21:42 被阅读57次

如何实现单例全局唯一


很多人看到标题可能会不屑一顾,单例本身就是全局唯一的啊,这也是我这几年一直坚信的从未怀疑的事实😂

static Manager *manager = nil;

+ (instancetype)managerCenter {
    
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
        manager = [[Manager alloc] init];
    });
    
    return manager;
}

相信大部分人都是这一种写法,简单直观又明了。但是假设一个在多人合作的项目里,同事B在不知Manager是单例的情况下调用了[Manager alloc]init; 验证一下就会发现这是一个新的对象,我写了快三年的居然到最近才发现这个事实😱。

那么如何保证无论使用者如何调用都保证单例的全局唯一

方法1:
使用NSAssert重现alloc方法如

+ (instancetype)alloc
{
    NSAssert(NO, @"请使用shared方法");
    return nil;
}

这种方法可以有效的提醒其他的程序员这是一个单例,但是只有等到运行时才能提示。

方法2:

static Manager *defaultManager = nil;
+ (Manager *)defaultManager
{
    @synchronized(self) //保证线程安全
    {
        if (defaultManager == nil)
        {
            defaultManager = [[self alloc] init];
        }
    }
    return defaultManager;
}

+ (id)allocWithZone:(NSZone *)zone
{
    @synchronized(self)
    {
        if (defaultManager == nil)
        {
            return [super allocWithZone:zone];
        }
    }
    return defaultManager;
}

- (id)init
{
    Class class = [self class];
    @synchronized(class)
    {
        if (defaultManager == nil)
        {
            if (self = [super init])
            {
                defaultManager = self; //使Manager赋值初始化
            }
        }
    }
    return  defaultManager;
}

运行如下测试代码,可以发现打印的结果都是一致的。

Manager *m1 = [Manager defaultManager];
NSLog(@"m1 : %p", m1);
Manager *m2 = [[Manager alloc]init];
NSLog(@"m2 : %p", m2);
Manager *m3 = [Manager alloc];
NSLog(@"m3 : %p", m3);
Manager *m4 = [Manager new];
NSLog(@"m4 : %p", m4);

关于@synchronized使用了线程锁详情参见这里 还有这里
这是我iOS遇坑填坑系列中的一篇,如果有大神发现其中的错误请指正,谢谢!

相关文章

  • Android面试记录#1:Android中单例模式的作用范围

    面试中被问到了老生常谈的单例模式,之前看得比较浅,只觉得单例模式保证对象的全局唯一性,那么这个“全局唯一性”针对一...

  • 我所理解的设计模式 —— 单例

    什么单例 单例是指整个程序中有且只有一个对象,具有全局唯一性,单例必须要自行创建一个实例,单例必须要始终提供一个全...

  • 单例模式(singleton)

    转载 确保对象的唯一性——单例模式 (一)确保对象的唯一性——单例模式 (二)确保对象的唯一性——单例模式 (三)...

  • 单例全局唯一性

    如何实现单例全局唯一 很多人看到标题可能会不屑一顾,单例本身就是全局唯一的啊,这也是我这几年一直坚信的从未怀疑的事...

  • 单例在Swift中的正确实现方式

    原文链接中文校对 单例三要素 唯一性:在一个应用程序的生命周期中,只有一个实例存在。单例提供了一个唯一的全局状态,...

  • iOS 单例的创建

    Objective-C创建单例 Swift创建单例 确保唯一性 复写allocWithZone、copyWithZ...

  • 单例模式

    单例模式保证全局唯一性,得考虑线程安全性延迟加载? 饿汉模式 线程安全的,但是不支持延迟加载(有问题早发现)① /...

  • 设计模式

    史上最全设计模式导学目录(完整版) 单例模式(Singleton Pattern) 确保对象的唯一性——单例模式 ...

  • 单例模式

    特点 单例类只有1个实例对象 该单例对象必须由单例类自行创建 单例类对外提供一个访问该单例的全局访问点 结构 单例...

  • C/C++转Rust的项目实践总结 6-10

    目录: 全局static变量6.1. lazy_static的局限 全局可变单例7.1. libstd的全局可变单...

网友评论

      本文标题:单例全局唯一性

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