OC:单例的写法之 ARC 和 MRC

说明 时间
首次发布 2017年06月23日
最近更新 2019年09月03日

单例手写

// .h
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface MZDaoManager : NSObject

+ (instancetype)shareManager;

@end

NS_ASSUME_NONNULL_END


// .m
#import "MZDaoManager.h"

// 1、提供全局变量
static MZDaoManager *_manager = nil;
@implementation MZDaoManager

// 2、alloc/new -> allocWithZone
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _manager = [super allocWithZone:zone];
        if ([_manager respondsToSelector:@selector(initData)]) {
            [_manager performSelector:@selector(initData)];
        }
    });
    return _manager;
}

// 3、提供类方法
+ (instancetype)shareManager {
    return [[self alloc] init];
}

// 4、严谨:兼容copy和mutableCopy
- (id)copyWithZone:(NSZone *)zone {
    return _manager;
}

- (id)mutableCopyWithZone:(NSZone *)zone {
    return _manager;
}

// 以下为兼容MRC,由于现在的工程绝大多数都是ARC,故可忽略。
#if !__has_feature(objc_arc)
- (NSUInteger)retainCount {
    return MAXFLOAT;
}

- (oneway void)release {}

- (instancetype)retain {
    return _manager;
}

#endif

@end

推荐:单例模式通用宏

#ifndef MZSingleInstance_h
#define MZSingleInstance_h

#define MZSingleInstanceH(name) + (instancetype)share##name;

#if __has_feature(objc_arc)
// ARC
#define MZSingleInstanceM(name)\
static id _manager = nil;\
+ (instancetype)allocWithZone:(struct _NSZone *)zone {\
    static dispatch_once_t onceToken;\
    dispatch_once(&onceToken, ^{\
        _manager = [super allocWithZone:zone];\
        if ([_manager respondsToSelector:@selector(initData)])\
            [_manager performSelector:@selector(initData)];\
    });\
    return _manager;\
}\
\
+ (instancetype)share##name {\
    return [[self alloc] init];\
}\
\
- (id)copyWithZone:(NSZone *)zone {\
    return _manager;\
}\
\
- (id)mutableCopyWithZone:(NSZone *)zone {\
    return _manager;\
}

#else

// MRC
#define MZSingleInstanceM(name)\
static id _manager = nil;\
+ (instancetype)allocWithZone:(struct _NSZone *)zone {\
    static dispatch_once_t onceToken;\
    dispatch_once(&onceToken, ^{\
        _manager = [super allocWithZone:zone];\
        if ([_manager respondsToSelector:@selector(initData)])\
            [_manager performSelector:@selector(initData)];\
        });\
    });\
    return _manager;\
}\
\
+ (instancetype)share##name {\
    return [[self alloc] init];\
}\
\
- (id)copyWithZone:(NSZone *)zone {\
    return _manager;\
}\
\
- (id)mutableCopyWithZone:(NSZone *)zone {\
    return _manager;\
}\
\
- (NSUInteger)retainCount {\
    return MAXFLOAT;\
}\
\
- (oneway void)release {}\
\
- (instancetype)retain {\
    return _manager;\
}
#endif

#endif /* MZSingleInstance_h */
使用:
// .h
#import <Foundation/Foundation.h>

#import "MZSingleInstance.h"

NS_ASSUME_NONNULL_BEGIN

@interface MZDaoManager : NSObject

MZSingleInstanceH(DaoManager)

@end

NS_ASSUME_NONNULL_END


// .m
#import "MZDaoManager.h"

@implementation MZDaoManager

MZSingleInstanceM(DaoManager)

@end
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容