美文网首页iOS 开发
单例模式和GCD单例实现

单例模式和GCD单例实现

作者: Mr丶炎 | 来源:发表于2016-07-28 08:56 被阅读326次

    1、传统单例模式
    2、GCD单例模式
    3、用宏实现GCD单例模式
    4、用宏实现GCD单例模式,名称随类名变化而变化

    单例模式一旦使用,将永远不死。不管是控制器还是类,尽管push,pop还是dismiss都不会死掉,下一次用到时还是第一次创建的那个类。

    1、看看传统单例模式的实现,要确保线程安全,一定要锁起来。

    // static 修饰的对象,只有在程序结束对才会被释放
    static id person;
    
    /**
     创建单例的步骤
     1.保留一个单例对象的静态实例
     2.声明和实现一个类方法,返回一个有值的该类对象
     3.重写allocWithZoon方法,做判空处理
     */
    
    // 单例的类方法命名一般用share+当前类名
    + (instancetype)sharedPerson {
        
        // synchronized能保证里面的内容同时只能被一个线程执行
        @synchronized(self) {
            
            // 先判断是否为空,如果为空再创建
            if (person == nil) {
                person = [[self alloc] init];
            }
        }
        
        return person;
    }
    
    + (instancetype)allocWithZone:(struct _NSZone *)zone {
        
        @synchronized(self) {
            if (person == nil) {
                person = [super allocWithZone:zone];
            }
        }
        return person;
    }
    
    - (id)copyWithZone:(NSZone *)zone {
        return person;
    }
    
    

    2、看看GCD实现,我们用的是once函数,它已经确保了线程安全问题

    static Car *_car;
    
    + (instancetype)allocWithZone:(struct _NSZone *)zone {
        
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            _car = [super allocWithZone:zone];
        });
        
        return _car;
    }
    
    + (instancetype)sharedCar {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            _car = [[self alloc] init];
        });
        return _car;
    }
    
    - (id)copyWithZone:(NSZone *)zone {
        return _car;
    }
    

    3、用宏实现GCD单例模式,当我们需要实现单例类时,其实代码完全是一样的,这样我们抽成宏,但是这个我们只能用同一的方法,sharedInstance。如果我们想这样,一个person类,那么单例就是sharedPerson,看第四份代码。这里\作用是,让宏识别到后面的代码,因为宏默认只识别它后面一行代码,加\就代表下一行也是

    // .h文件
    #define SingletonH  + (instancetype)sharedInstance;
    
    // .m文件
    #define SingletonM \
    \
    static id _instance;\
    \
    + (instancetype)allocWithZone:(struct _NSZone *)zone {\
        \
        static dispatch_once_t onceToken;\
        dispatch_once(&onceToken, ^{\
            _instance = [super allocWithZone:zone];\
        });\
        \
        return _instance;\
    }\
    \
    + (instancetype)sharedInstance {\
        static dispatch_once_t onceToken;\
        dispatch_once(&onceToken, ^{\
            _instance = [[self alloc] init];\
        });\
        return _instance;\
    }\
    \
    - (id)copyWithZone:(NSZone *)zone {\
        return _instance;\
    }
    

    4、用宏实现GCD单例模式,名称随类名变化而变化。这里需要注意,name都是传过来的,所有在用时.h和.m都要传name

    像这样
    SingletonH(Car)
    SingletonM(Car)

    // .h文件
    #define SingletonH(name)  + (instancetype)shared##name;
    
    // .m文件
    #define SingletonM(name) \
    \
    static id _instance;\
    \
    + (instancetype)allocWithZone:(struct _NSZone *)zone {\
        \
        static dispatch_once_t onceToken;\
        dispatch_once(&onceToken, ^{\
            _instance = [super allocWithZone:zone];\
        });\
        \
        return _instance;\
    }\
    \
    + (instancetype)shared##name {\
        static dispatch_once_t onceToken;\
        dispatch_once(&onceToken, ^{\
            _instance = [[self alloc] init];\
        });\
        return _instance;\
    }\
    \
    - (id)copyWithZone:(NSZone *)zone {\
        return _instance;\
    }
    

    相关文章

      网友评论

        本文标题:单例模式和GCD单例实现

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