​    ​单例模式算是设计模式中比较简单的一种吧,设计模式不是只针对某种编程语言,在C++, Java, PHP等其他OOP语言也有设计模式,笔者初接触设计模式是通过《漫谈设计模式》了解的。这本书中是用java写的,个人感觉拜读完这本书以后虽然有不理解的地方但还是收获蛮大的。上面提到依赖注入,控制翻转的时候,没大看懂,当学习到Strut,Spring, Hibernate的东西的时候才略懂略懂。不过在23种设计模式里面单例模式还是算比较好理解的, 那么在OC中又是怎么来表示单例模式的呢?下面会结合着代码,理解一下OC中得单例模式。

​    ​首先得了解什么是单例模式,用大白话说,单例模式就是在程序中这个类只对应着一个实例,这就是单例模式,单例模式一般用全局静态对象来实现。下面我们会建立一个生成单例的类SingletonClass,在实现文件中定义各种方法来实现我们的单例模式。

​    ​1.单例模式一般用全局静态对象来实现,所以我们在SingletonClass.m中定义一个静态全局变量是少不了的

1
2
//定义静态全局变量
static SingletonClass *single = nil;

​    ​2.上面的静态变量是定义在实现文件中的所以是私有的,要想获取该类的实例得有个getInstance方法来获取实例,在给静态变量分配内存空间之前首先要判断是否已经分配过啦,确保单例,如果分配过了就不分配了。

1
2
3
4
5
6
7
8
9
//获取静态全局对象
+(id)getInstance
{
    //如果没有生成对象,则为静态全局变量分配内存
    if (single == nil) {
        single = [[SingletonClass alloc] init];
    }
    return single;
}

​    ​

​    ​3.为了防止用户通过alloc和new来实例化对象,因此我们要对类方法allcoWithZone进行重写

1
2
3
4
5
6
7
8
//防止通过alloc或者new来创建新的对象我们要重写allocWithZone
+(id)allocWithZone:(NSZone *)zone
{
    if (single == nil) {
        single = [[super allocWithZone:zone] init];
    }
    return single;
}

​    ​4.为了防止用户把单例进行深浅拷贝,我们需要重写copyWithZone方法和mutableCopyWithZone方法,在重写方法之前我们的单例类必须遵循协议NSCoping和NSMutableCoping协议

​    ​遵循协议代码如下:

1
2
3
4
5
6
7
8
9
@interface SingletonClass : NSObject<NSCopying, NSMutableCopying>
 
//单例中获取单例对象的方法
+(id) getInstance;
 
//单例测试方法
-(void) singletonFunction;
 
@end

​    ​重写copyWithZone方法

1
2
3
4
5
//为了防止通过copy来创建新的实例我们要重写copyWithZone;
-(id)copyWithZone:(NSZone *)zone
{
    return self;
}

​    ​重写mutableCopyWithZone方法

1
2
3
4
-(id)mutableCopyWithZone:(NSZone *)zone
{
    return self;
}

​5.防止用户把创建的单例dealloc,我们需要重写retainCount方法

1
2
3
4
5
//重写retainCount方法,防止被dealloc,返回最大值
-(NSUInteger) retainCount
{
    return NSUIntegerMax;
}

​6. 重写release,autorelease, retain方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//重写retain,引用计数不变
-(id) retain
{
    return self;
}
 
//重写release
-(oneway void) release
{
}
 
//重写autorelease
-(id) autorelease
{
    return self;
}

​至此我们的单例模式基本创建完毕,下面开始我们的测试吧;

​在main函数中的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//单例模式的测试
SingletonClass *single1 = [SingletonClass getInstance];
SingletonClass *single2 = [SingletonClass new];
SingletonClass *single3 = [[SingletonClass alloc] init];
SingletonClass *single4 = [single1 copy];
SingletonClass *single5 = [single1 mutableCopy];
SingletonClass *single6 = [single1 retain];
[single1 release];
 
[single1 singletonFunction];
NSLog(@"single_retainCount = %lu", single1.retainCount);
 
//输出地址
NSLog(@"getInstance     single1_P = %p", single1);
NSLog(@"new             single2_P = %p", single2);
NSLog(@"allo            single3_P = %p", single3);
NSLog(@"copy            single4_P = %p", single4);
NSLog(@"mutableCopy     single5_P = %p", single5);
NSLog(@"retain          single6_P = %p", single6);

​    ​运行结果如下:

1
2
3
4
5
6
7
8
2014-08-07 16:04:44.207 Memory[20664:303] singleton Ps: 我是单例模式中得测试方法!!
2014-08-07 16:04:44.207 Memory[20664:303] single_retainCount = 18446744073709551615
2014-08-07 16:04:44.207 Memory[20664:303] getInstance     single1_P = 0x100204690
2014-08-07 16:04:44.208 Memory[20664:303] new             single2_P = 0x100204690
2014-08-07 16:04:44.208 Memory[20664:303] alloC            single3_P = 0x100204690
2014-08-07 16:04:44.208 Memory[20664:303] copy            single4_P = 0x100204690
2014-08-07 16:04:44.209 Memory[20664:303] mutableCopy     single5_P = 0x100204690
2014-08-07 16:04:44.209 Memory[20664:303] retain          single6_P = 0x100204690

​    ​    ​单例的地址是不变的。

    上面是在非ARC模式下得单例模式,那么在ARC模式下我们应如何实现我们的单例模式呢,我们下面就会给出ARC下的单例模式,用下面的方法,因没有重写alloc,copy等方法,通过alloc还是可以给该对象分配一个新对象的,上面是线程不安全的,下面是线程安全的:

 + (id)sharedSingleton {
static MySingleton *sharedSingleton = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedSingleton = [[self alloc] init];
});
return sharedSingleton;
}

Objective-C中的单例模式的更多相关文章

  1. C# 中实现单例模式

    文章目录 简介 不安全线程的单例模式 简单安全线程带锁 双重检查 - 带锁 安全初始化 安全并且懒汉式静态初始化 带泛型的懒汉式单例 异常 提高效率 总结 简介 单例模式是软件工程中广为人知的设计模式 ...

  2. 转:C++中的单例模式

    C++中的单例模式 单例模式也称为单件模式.单子模式,可能是使用最广泛的设计模式.其意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享.有很多地方需要这样的功能模块, ...

  3. 浅谈iOS中的单例模式

    iOS中的单例模式     就我本身理解而言,我认为的单例:单例在整个工程中,就相当于一个全局变量,就是不论在哪里需要用到这个类的实例变量,都可以通过单例方法来取得,而且一旦你创建了一个单例类,不论你 ...

  4. 理解Objective C 中id

    什么是id,与void *的区别 id在Objective C中是一个类型,一个complier所认可的Objective C类型,跟void *是不一样的,比如一个 id userName, 和vo ...

  5. 浅谈Objective—C中的面向对象特性

    Objective-C世界中的面向对象程序设计 面向对象称程序设计可能是现在最常用的程序设计模式.如何开发实际的程序是存在两个派系的-- 面向对象语言--在过去的几十年中,很多的面向对象语言被发明出来 ...

  6. 关于JDK中采用单例模式的类

    JDK设计模式应用——单例模式(Singleton) <JDK源码分析>的分支,讲解设计模式在jdk中使用. 我们从三个方面讲述,一是:jdk源码中的设计模式:二是:讲解设计模式(UML图 ...

  7. java中的单例模式与doublecheck

    转自: http://devbean.blog.51cto.com/448512/203501 在GoF的23种设计模式中,单例模式是比较简单的一种.然而,有时候越是简单的东西越容易出现问题.下面就单 ...

  8. java中的单例模式与静态类

    单例模式与静态类(一个类,所有方法为静态方法)是另一个非常有趣的问题,在<Java中有关单例模式的面试问题>博文中露掉了,由于单例模式和静态类都具有良好的访问性,它们之间有许多相似之处,例 ...

  9. 【译】在C#中实现单例模式

    目录 介绍 第一个版本 --不是线程安全的 第二个版本 -- 简单的线程安全 第三个版本 - 使用双重检查锁定尝试线程安全 第四个版本 - 不太懒,不使用锁且线程安全 第五版 - 完全懒惰的实例化 第 ...

随机推荐

  1. 踏上Salesforce的学习之路(二)

    一.添加一个字段到对象中 1.给Merchandise对象添加一个Price字段 先点击右上角姓名旁边的Setup(不管你在哪个页面,点击Setup都能让你快速的回到首页,如下图所示),然后在左侧的Q ...

  2. 基于黑名单的xss过滤器

    /** * 类名称:AntiXssFilter * @version * 类描述:基于黑名单的xss过滤器 * @version * 创建人:xxx * @version * 创建时间:2015年11 ...

  3. (转)对博士学位说永别 by 王珢

    对博士学位说永别 by 王垠 经过深思熟虑之后,我决定再次“抛弃”我的博士学位.这是我第三次决定离开博士学位,也应该是最后一次了.这应该不是什么惊人的消息,因为我虽然读博士10年了,可是我的目标从来就 ...

  4. flex的兼容

    父容器的 display 属性: .box{ display: -webkit-box; /* 老版本语法: Safari, iOS, Android browser, older WebKit br ...

  5. indexOf、instanceOf、typeOf、valueOf详解

    1.indexOf() 该方法用来返回某个指定的字符串值在字符串中首次出现的位置. 语法:indexOf(searchvalue,fromindex);两个参数,参数一表示查询的字符串值,参数二可选表 ...

  6. easyui-conbotree树形下拉框。。。转

    最近一直在研究这个树形的下拉选择框,感觉非常的有用,现在整理下来供大家使用: 首先数据库的表架构设计和三级菜单联动的表结构是一样,(父子关系) 1.下面我们用hibernate建一下对应的额实体类: ...

  7. QQ表情的发送与接收

    我想大家对QQ表情一定不会陌生,一个个小头像极大丰富了聊天的乐趣,使得聊天不再是简单的文字叙述,还能够配上喜.怒.哀.乐等表达人物心情的小图片.本文重点要介绍的内容就是如何在微信公众平台使用QQ表情, ...

  8. IPC操作时IPC_CREAT和IPC_EXCL选项的说明

    IPC(包括消息队列,共享内存,信号量)的xxxget()创建操作时,可以指定IPC_CREAT和IPC_EXCL选项.以共享内存为例:当只有IPC_CREAT选项打开时,不管是否已存在该块共享内存, ...

  9. C#模拟http 发送post或get请求

    /// <summary> /// 模拟HTTP提交表单并获取返回数据 /// POST /// </summary> /// <param name="Url ...

  10. SQL Server2005清除数据库日志

     SQL2005清空删除日志: 复制代码 代码如下: Backup Log DNName with no_log  '这里的DNName是你要收缩的数据库名,自己注意修改下面的数据库名,我就不再注释了 ...