ios开发答疑录系列​--关于IOS单利的思考

来源:互联网 发布:2017笔记本电脑知乎 编辑:程序博客网 时间:2024/05/21 10:12

============================================================
博文原创,转载请声明出处
电子咖啡(原id蓝岩)
============================================================
近日我写了一段单利代码,如下,有些思考

#import "WQPlaySound.h"#define DISPOSE_INTERVAL 3@implementation WQPlaySoundstatic 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 Singletonstatic Singleton* instance=nil;static int i=0;+(Singleton*)share{    NSLog(@"self:%@----i++:%d",self,i++);        @synchronized(instance){//注意这次是instance不是self        if (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++:02012-11-06 17:21:46.934 SingletonDemo[811:4303] self:Singleton----i++:12012-11-06 17:21:46.934 SingletonDemo[811:4603] self:Singleton----i++:22012-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++:02012-11-06 17:41:32.863 SingletonDemo[866:4103] self:Singleton----i++:22012-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中继续研究


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 w10升级系统卡死怎么办 答题卡写错位置怎么办 高考答错区域该怎么办 荒野行动画面中间有条横怎么办 荒野行动pc闪退怎么办 幽灵行动荒野子弹没了怎么办 看门狗2枪没子弹怎么办 爱奇艺不小心删除了本地视频怎么办 80岁老太太就爱闹肚子怎么办? 皇牌空战5弹药不够怎么办 辐射4玩着头晕怎么办 官司打赢了法院不给钱怎么办 电脑玩dnf太卡怎么办 soul被禁止私聊怎么办 刺激战场空投挂树上怎么办 由于经济原因心态不好怎么办 公司经济不好不裁员怎么办 家里经济不好没有钱怎么办 银行柜员找不到工作怎么办 在球队中打替补怎么办 大学生毕业后找不到工作怎么办 30岁不敢换工作怎么办 投完简历没回复怎么办 工业废气一年总量超标怎么办 安监局行政处罚没能力交怎么办 被社会淘汰的人怎么办 宝宝吐奶的时候怎么办 网友要我发红包怎么办 电脑久了很慢怎么办 影驰显卡花屏怎么办 反恐精英全球攻势加载地图慢怎么办 老滚5视角锁死了怎么办 苹果描述文件没有了怎么办 苹果6s发热严重怎么办 苹果6s发烫严重怎么办 手机型号不适配全军出击怎么办? 苹果5版本过低怎么办 在泰国买到假货怎么办 在泰国旅游遇到危险该怎么办? 拾到小米手环怎么办 苹果充电打游戏触点怎么办