iOS学习之单例

来源:互联网 发布:网络预约车管理办法 编辑:程序博客网 时间:2024/06/03 19:08

单例模式的作用:可以保证在程序运行过程中,一个类只有一个实例,而且该实例易于外界访问(说白了就是节省一些内存),其实面试的时候也就是让你手动写下单例,基本固定用GCD,没什么技术含量,平时放在一个类里面或者快捷方式里面就好了

.h文件

#import <Foundation/Foundation.h>@interface SLDemo : NSObject<NSCopying>+ (instancetype)sharedInstance;@end

.m文件

id _testStr = @"testStr";static id _instance; //static修饰一个全局变量,表示该变量只能本文件内部访问,外部无法访问 修改,用来保存唯一的单例对象+ (instancetype)allocWithZone:(struct _NSZone *)zone {    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        _instance = [super allocWithZone:zone]; //申请内存    });//    if (_instance == nil) { //防止频繁加锁//        @synchronized(self) {//            if (_instance == nil) { //防止多次创建//                _instance = [super allocWithZone:zone];//            }//        }//    }    return _instance;}+ (instancetype)sharedInstance {    NSLog(@"%@",_testStr);    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        _instance = [[self alloc] init]; //调用allocWithZone    });//    if (_instance == nil) { //防止频繁加锁//        //防止多线程一起进来,加锁//        @synchronized(self) {//            if (_instance == nil) { //防止多次创建//                _instance = [[self alloc] init];//            }//        }//    }    return _instance;}- (id)copyWithZone:(NSZone *)zone {    return _instance;}@end

调用

- (void)viewDidLoad {    [super viewDidLoad];    [self createSLDemo];    }- (void)createSLDemo {        //extern关键字是告诉编译器整个工程搜索id _testStr的全局变量,我们就可以更改搜索到后    extern id _testStr;    _testStr = @"string";    SLDemo * SL1 = [SLDemo sharedInstance];    SLDemo * SL2 = [SLDemo sharedInstance];    SLDemo * SL3 = [SLDemo sharedInstance];    SLDemo * SL4 = [SLDemo sharedInstance];        NSLog(@"%@ %@ %@ %@",SL1, SL2, SL3, SL4);    }@en

会发现打印出的地址是一样的四个,证明只调用了一次,创建了一个共同的实例

解释:上面.m文件用的是static修饰,假如去掉static,就像extern一样,拿出来可以改变,这样单例就很危险了,很可能会被其他人修改,那这样就不叫单例了

上面的单例还可以写在一个文件里,用宏调用,比如:

//.h文件宏#define SLDemoH(name) + (instancetype)shared##name;//.m文件宏#define SLDemoM \id _testStr = @"testStr"; \static id _instance; \ \+ (instancetype)allocWithZone:(struct _NSZone *)zone \{\    static dispatch_once_t onceToken; \    dispatch_once(&onceToken, ^{ \        _instance = [super allocWithZone:zone];  \//申请内存    }); \    //    if (_instance == nil) { //防止频繁加锁    //        @synchronized(self) {    //            if (_instance == nil) { //防止多次创建    //                _instance = [super allocWithZone:zone];    //            }    //        }    //    }    return _instance;}+ (instancetype)shared##name {    NSLog(@"%@",_testStr);    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        _instance = [[self alloc] init]; //调用allocWithZone    });    //    if (_instance == nil) { //防止频繁加锁    //        //防止多线程一起进来,加锁    //        @synchronized(self) {    //            if (_instance == nil) { //防止多次创建    //                _instance = [[self alloc] init];    //            }    //        }    //    }    return _instance;}- (id)copyWithZone:(NSZone *)zone {        return _instance;}

再就是可以用条件编译区分ARC 和 MRC


0 0
原创粉丝点击