单例其实和C语言中的全局变量是差不多的。在整个程序的生命周期中只有一份内存,可以在多个程序中数据共享。最常见的单例写法其实就是
static Manger *manger=nil;
+(Manger *)shardeManger
{
if(manger==nil)
{
manger=[[[self class]alloc]init];
}
return manger;
}
-(id)init
{
self=[super init];
if(self)
{
}
return self;
}
如果在多线程中,在manger还是nil的时候有多个线程进行访问,比如说,一个线程在运行到shardeManger方法中的alloc那个位置,而另一个线程也调用到了那个位置,然后这个线程进行一次实例化,那个线程也进行了实例化,内存就会被覆盖,我们希望得到的关于那个单例的一些数据就不会那么的准确了。这个时候我们也是有解决办法的。就是加锁。
static Manger *manger=nil;
+(Manger *)shardeManger
{
@synchronized(self)
{
if(manger==nil)
{
manger=[[[self class]alloc]init];
}
}
return manger;
}
或者我们还可以用GCD的一个方法只执行一次。
+(Manger *)shardeManger
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken,^{
manger =[[[self class]alloc]init];
});
return manger;
}
alloc会默认调用allocWithZone方法来分配内存空间,我们要单例设计的时候要重写allocwithzone的方法不然的话就可以调用allocwithzone这个方法又生成的一个单例
+(id)allocWithZone:(struct _NSZone *)zone
{
//里面的代码只会执行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manger =[super allocWithZone:zone];
});
return manger;
}