有好多人写单例喜欢用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;
}