ios-单例模式饿汉式&GCD&懒汉式&宏方式的实现和条件编译

来源:互联网 发布:exe软件 编辑:程序博客网 时间:2024/05/18 19:44

饿汉式其实就是当程序一启动就是创建单例,在ios中不推荐去使用

static id instance;+ (void)load //装载内存时就实例化,仅此一次{    _instance = [[self alloc] init];}+ (id)allocWithZone:(struct _NSZone *)zone{         //这里可以不用加锁,因为是在load里面创建的    if (_instance == nil) { // 防止创建多次        _instance = [super allocWithZone:zone];    }    return _instance;}+ (instancetype)sharedManagerTool{    return _instance;}- (id)copyWithZone:(NSZone *)zone{    return _instance;}
GCD的单例实现方式

static id _instace;+ (id)allocWithZone:(struct _NSZone *)zone{    static dispatch_once_t onceToken;    //这个函数是线程安全的    dispatch_once(&onceToken, ^{        _instace = [super allocWithZone:zone];    });    return _instace;}+ (instancetype)sharedDataTool{    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        _instace = [[self alloc] init];    });    return _instace;}- (id)copyWithZone:(NSZone *)zone{    return _instace;}
懒汉式的实现就是在用到的时候再去创建

static id _instance;//alloc内部会调用这个代码+ (id)allocWithZone:(struct _NSZone *)zone{    if (_instance == nil) { // 防止频繁加锁        @synchronized(self) {            if (_instance == nil) { // 防止创建多次                _instance = [super allocWithZone:zone];            }        }    }    return _instance;}+ (instancetype)sharedMusicTool{    if (_instance == nil) { // 防止频繁加锁        @synchronized(self) {            if (_instance == nil) { // 防止创建多次                _instance = [[self alloc] init];            }        }    }    return _instance;}- (id)copyWithZone:(NSZone *)zone{    return _instance;}
非ARC下的单例模式

static id _instace;+ (id)allocWithZone:(struct _NSZone *)zone{    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        _instace = [super allocWithZone:zone];    });    return _instace;}+ (instancetype)sharedDataTool{    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        _instace = [[self alloc] init];    });    return _instace;}- (id)copyWithZone:(NSZone *)zone{    return _instace;}//为了保证对象不被释放,所以在release中不做任何操作-(oneway void)release{}//retain的时候返回自己- (id)retain{    return self;}- (NSUInteger)retainCount{    return 1;}//这里其实加不加都一样,因为最后会调用release操作,而我们又重写了release方法- (id)autorelease {        return self;}
因为我们如果每用到一个类就要去复制这些代码,所以我们可以把这些代码定义成宏,确定就是不好调试。\这个的意思就是后面的一行都是它的.我们想用的话想把sharedInstance的Instance的名字改成我们自己传的名字,下面加()和传入参数name

// .h文件#define SingletonH(name) + (instancetype)shared##name;// .m文件#define SingletonM(name) \static id _instance; \ \+ (id)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; \}

我们在写项目的时候如果想要指定在ARC下执行什么代码,在MRC下执行什么代码,我们可以用条件编译来写

#if __has_feature(objc_arc)    //编译环境是ARC    NSLog(@"kkk");#else    //编译环境是MRC    NSLog(@"kkk");#endif




原创粉丝点击