本文主要是介绍ios开发答疑录系列--关于IOS单利的思考,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
#import "WQPlaySound.h"
#define DISPOSE_INTERVAL 3@implementation WQPlaySound
static WQPlaySound* instance=nil;
static NSString* lock=@"";+(WQPlaySound*)shareWQPlaySound{ //同步防止多线程访问,这里本来想用instance来作为锁对象的,但是当instance为nil的时候不能作为锁对象@synchronized(lock){if (!instance) {instance= [[WQPlaySound alloc]init];}}return instance;
}
问题一:单利需要release吗?
No class should need to retain a pointer to a singleton class. Singleton class itself keeps a pointer to its instance. Basically, when the user wants to use a singleton, they will request it through a class method (by convention often starting with shared
). This method will check if the singleton has been initialized. If not, it will perform the initialization. If there is already an existing instance in memory, it will just return it. Usually, a singleton object will live in memory for the life of the application.
单利生命周期和appdelegate是一样的,因此不需要release
问题二:@synchronized(lock){...}的lock同步锁对象如果是空的话,还工作吗?
Nil value used as mutex for @synchronized() (no synchronization will occur)
这是xcode提示我的,因此不可以用nil,我们可以用空字符串@“”来加锁
修改----2012-11-06
刚才@DolphinOrca 对我的代码提出了疑问,我测试了一下,却是是我的理解错误,在此表示对DolphinOrca 的感谢。
DolphinOrca提出把@synchronized(lock) 替换成@synchronized(self)可以更方便的进行同步。而我当时认为这样子不可以,因为在@synchronized(self) 的时候,self还没有被init,所以self是nil,synchronized(nil)无效。
后来我又做了实验,证明我的观点是错误的。
首先新建单利Singleton
@implementation Singleton
static Singleton* instance=nil;
static int i=0;
+(Singleton*)share{NSLog(@"self:%@----i++:%d",self,i++); @synchronized(instance){//注意这次是instance不是selfif (instance==nil) { if((i)>1){ //i>1是为了前两个线程在这里停留两秒,让第三个线程先alloc然后自己再alloc[NSThread sleepForTimeInterval:2];}instance = [[Singleton alloc] init];}}return instance;
}
然后在另一个文件中启动三个线程去获得这个单利,然后打印看三个单利是否相同。
- (void)viewDidLoad
{[super viewDidLoad];//启动三个线程去调用单利 [NSThread detachNewThreadSelector:@selector(getSingleton) toTarget:self withObject:nil];[NSThread detachNewThreadSelector:@selector(getSingleton) toTarget:self withObject:nil];[NSThread detachNewThreadSelector:@selector(getSingleton) toTarget:self withObject:nil];
}
-(void)getSingleton{Singleton* s= [Singleton share];NSLog(@"signle:%@",s);
}
结果如下
2012-11-06 17:21:46.933 SingletonDemo[811:3c07] self:Singleton----i++:0
2012-11-06 17:21:46.934 SingletonDemo[811:4303] self:Singleton----i++:1
2012-11-06 17:21:46.934 SingletonDemo[811:4603] self:Singleton----i++:2
2012-11-06 17:21:48.948 SingletonDemo[811:4603] signle:<Singleton: 0x744a5e0> //<<<<--------
2012-11-06 17:21:48.948 SingletonDemo[811:4303] signle:<Singleton: 0x91174a0>
2012-11-06 17:21:48.948 SingletonDemo[811:3c07] signle:<Singleton: 0x714b6e0>
可以看到输出的singleton对象为三个不同的对象,这是我原来的思想。
线面我门将synchronized锁换成self,其他不变,重新运行,
@synchronized(self)
输出结果为:
2012-11-06 17:41:32.863 SingletonDemo[866:4603] self:Singleton----i++:1 //self为Singleton类
2012-11-06 17:41:32.863 SingletonDemo[866:3c07] self:Singleton----i++:0
2012-11-06 17:41:32.863 SingletonDemo[866:4103] self:Singleton----i++:2
2012-11-06 17:41:34.879 SingletonDemo[866:4603] signle:<Singleton: 0x750e120>
2012-11-06 17:41:34.879 SingletonDemo[866:3c07] signle:<Singleton: 0x750e120>
2012-11-06 17:41:34.879 SingletonDemo[866:4103] signle:<Singleton: 0x750e120>
可以看到获得的单利为同一对象。
后来思考,这里self是以类class为锁,所以不存在nil的问题。
关于线程同步的问题,我会在以后的blog中继续研究
这篇关于ios开发答疑录系列--关于IOS单利的思考的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!