iOS单粒设计

2017-08-27  本文已影响0人  叶子扬

单粒设计模式能为全局提供同一个对象,因此,这个对象只需要创建一次,比如一个应用的登录页面。

示例代码:
//.h

@interface YYCar : NSObject
+ (instancetype)sharedCar;
@end

//.m

@implementation YYCar
// static 限制访问范围只在.m内
static YYCar *_car;

// 该处的alloc方法会触发父类的allocWithZone:方法,
// 为了防止外界直接使用allocWithZone:方法时返回nil,因此需重写该方法
// copyWithZone:方法同理

+ (instancetype)sharedCar
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _car = [[self alloc] init];
    });
    return _car;
}

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

有追求的程序员应该要想到,这个过程太啰嗦,况且,所有创建单粒的方法都长一个样,升级版的做法是把创建单粒的方法都抽出来,如下(只需要一个.h文件):

#define YYInstanceH + (instancetype)sharedInstance;

#define YYInstanceM \
 \
static id _instance; \
 \
+ (instancetype)sharedInstance \
{ \
    static dispatch_once_t onceToken; \
    dispatch_once(&onceToken, ^{ \
        _instance = [[self alloc] init]; \
    }); \
    return _instance; \
} \
 \
+ (instancetype)allocWithZone:(struct _NSZone *)zone \
{ \
    static dispatch_once_t onceToken; \
    dispatch_once(&onceToken, ^{ \
        _instance = [super allocWithZone:zone]; \
    }); \
    return _instance; \
} \
 \
- (id)copyWithZone:(NSZone *)zone \
{ \
    return _instance; \
}
更高逼格的改进

上边的方法的确达到了“快、准、狠”的效果,不过,有时候有些场景需要在获取单粒的方法后边使用单粒的名称,就像sharedApplicatioin一个具体、形象、生动, 传入一个单粒名称即可:

#define YYInstanceH(name) + (instancetype)shared##name;

#define YYInstanceM(name) \
\
static id _instance; \
\
+ (instancetype)shared##name \
{ \
    static dispatch_once_t onceToken; \
    dispatch_once(&onceToken, ^{ \
        _instance = [[self alloc] init]; \
    }); \
    return _instance; \
} \
\
+ (instancetype)allocWithZone:(struct _NSZone *)zone \
{ \
    static dispatch_once_t onceToken; \
    dispatch_once(&onceToken, ^{ \
        _instance = [super allocWithZone:zone]; \
    }); \
    return _instance; \
} \
\
- (id)copyWithZone:(NSZone *)zone \
{ \
    return _instance; \
}
上一篇 下一篇

猜你喜欢

热点阅读