iOS allocWithZone写单例遇到的坑

2016-12-27  本文已影响0人  huisedediao

有好多人写单例喜欢用allocWithZone,这里说下自己遇到的坑。

先看下面的写法:

+(instancetype)shareManager
{
    return [XBDownloadTaskManager new];
}

-(instancetype)init
{
    if (self=[super init])
    {
          self.taskList=[NSMutableArray new];
    }
    return self;
}

+(instancetype)allocWithZone:(struct _NSZone *)zone
{
    static XBDownloadTaskManager *task=nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        task=[super allocWithZone:zone];
    });
    return task;
}

似乎没有什么不对。
但是,打印该单例的taskList的时候,发现每次打印: [XBDownloadTaskManager shareManager].taskList ,taskList的内存地址都是不同的,就是这个坑了。

以为allocWithZone只分配一次内存,init 这个方法也只执行一次。而事实上,在 shareManager 方法中调用 [XBDownloadTaskManager new] ,每次都会调用init方法,每次都调用allocWithZone方法,确实是只分配了一次内存,但是if (self=[super init])这个条件是成立的,所以内次都跑了,所以,如果在init方法里有对属性的相关操作,也要加once操作

修改版:

-(instancetype)init
{
    if (self=[super init])
    {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            self.taskList=[NSMutableArray new];
        });
    }
    return self;
}
上一篇 下一篇

猜你喜欢

热点阅读