首页 > 学院 > 开发设计 > 正文

设计模式-02-单例

2019-11-14 18:20:24
字体:
来源:转载
供稿:网友

完整的单例通常需要实现三个方法(GCD)


  • share方法

    + (instancetype)sharePerson{    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        _person = [[self alloc] init];    });    return _person;}
  • alloc方法

    + (instancetype)allocWithZone:(struct _NSZone *)zone{    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        _person = [super allocWithZone:zone];    });    return _person;}
  • copy方法

    - (id)copyWithZone:(NSZone *)zone{    return _person;}

通过宏实现单例(GCD方式)


  • 代码如下:

    //.h文件#define LYPSingletonH(name) + (instancetype)share##name;//.m文件#define LYPSingletonM(name) /static id _instance; / /+ (instancetype)share##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; /}
  • 注意事项

    • 每行后边的/表示下一行与该部分也是一个整体
    • .h文件下的一行要加分号,否则在引用的时候要加分号
    • 定义宏的新名字后边必须加空格,因为编译器,默认将新名字开始遇到的第一个空格前的部分作为宏的名字

通过非GCD方式实现单例


  • 实现代码如下

    static Dog *_dog;+ (instancetype)shareDog{    @synchronized(self)    {        if (_dog == nil)        {            [NSThread sleepForTimeInterval:3];            _dog = [[self alloc] init];        }    }    return _dog;}+ (instancetype)allocWithZone:(struct _NSZone *)zone{    @synchronized(self)    {        if (_dog == nil)        {            [NSThread sleepForTimeInterval:3];            _dog = [super allocWithZone:zone];        }    }    return _dog;}- (id)copyWithZone:(NSZone *)zone{    return _dog;}
  • 注意事项

    • 为创建对象是分配内存和初始化的代码加锁,若不加锁,当多个线程并发执行创建对象任务,将会破坏单例模式,创建出多个对象(通常在创建对象耗时比较长的时候发生)
      @synchronized(self) {}

注意


1.单例模式不能使用继承实现,否则所有子类创建的对象都将是第一个创建的对象


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表