一 何为单例singleton模式?(what)

保证一个类只有一个实例,并提供一个访问它的全局访问点。

二 何时使用单例模式?(where)

1类只能有一个实例,而且必须从一个为人熟知的访问点对其访问,比如工厂方法。

2这个唯一实例只能通过子类化进行扩展,而且扩展的对象不会破坏客户端代码。

为什么不用静态全局变量或是类方法呢?

如果一个程序中两个人分别在两个地方定义了相同类型的静态变量。那么一个程序中就会有两个相同的全局对象类型。

类方法提供了共享服务,不用创建其对象就可以访问,资源的唯一实例可以在类方法中进行维护。但是如果累需要被子类化以提供更好的服务,这一方式就不灵活。

三 实现单例模式 (how)

static Singleton *sharedSingleton_=nil;

+(Singleton *)sharedInstance

{

  if(sharedSingleton_==nil){
    sharedSingleton = [[Singleton alloc]init];

  }

  return sharedSingleton_;

}

需克服问题:

发起调用的对象不能以其他方式实例化单例对象。否则就可能创建单例类的多个实例。

对单例对象实例化的限制应该与引用计数内存模型共存。

解决:

static Singleton *sharedSingleton_=nil;

+(Singleton *)sharedInstance

{

  if(sharedSingleton_==nil){
    sharedSingleton = [[super allocWithZone:NULL]init];

  }

  return sharedSingleton_;

}

用super的原因是,已经在self中重载了基本对象分配方法,需要借用父类来帮助处理底层内存分配的复杂任务

+(id)allocWithZone:(NSZone *)zone

{

  return [[self sharedInstance] retain];//为什么retain,是有了把Singleton类变得不太严格的一种选择(即允许分配与初始化额外的实例,但shareInstance工厂方法总是返回同一个实例,否则singleton对象可能被破坏)子类可以再次重载retain、release和autorelease方法,实现合适的内存管理。

}

- (id)copyWithZone:(NSZone *)zone

{

  return self;

}

- (NSUInteger)retain

{

  return self;

}

- (NSUInteger)retainCount

{

  return NSUIntegerMax;//4294967295

}

- (void)release

{  

//生么也不做

}

- (id)autorelease

{

  return self;

}

alloc使用设为NULL的zone来调用allocWithZone:在默认区域为新实例分配内存。

四 子类化单例

如果用以上的方法,不做修改的子类化Singleton时,返回的实例总是Singleton,因为Singleton重载了所有实例化相关的方法。

解决方法:

+(Singleton *)sharedInstance

{

  if(sharedSingleton_==nil){
    sharedSingleton = [NSAllocateObject([self class],0,NULL) init];

  }

  return sharedSingleton_;

}

第一个参数是类型,第二个参数是用于索引实例变量的额外字节数总是0,第三个参数用于指定内存中分配的区域一般为NULL表示默认区域。可以通过指定类的类型,用这个函数实例化任何对象。

五 还要注意单例对象的线程安全

@synchoronized()或NSLock或是dispatch_once

OC编程之道-创建对象之单例模式的更多相关文章

  1. OC编程之道-创建对象之抽象工厂方法

    定义:提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类.       <AbstractProductA> <AbstractProductB> <Ab ...

  2. OC编程之道-创建对象之工厂方法

    一 何为工厂方法模式?(what) 定义创建对象的接口,让子类决定实例化哪一个类,工厂方法是的一个类的实例化延迟到其子类. 工厂方法创建的对象拥有一组共同的行为,所以往类层次结构中引入新的具体产品并不 ...

  3. OC编程之道-创建对象之原型模式

    一 什么是原型模式?(what) 有些对象的创建代价过大或过于复杂,要是可以重建相同的对象并作轻微的改动,事情会容易的多(效率变高).典型的例子是复制组合结构(eg树形结构),从零开始构建一个树型组合 ...

  4. OC编程之道-创建对象之生成器模式

    生成器模式也叫建造者模式,一般是用来构造复杂对象的一种模式.client(客户)-director(指导者)-builder(构造者)-product(产品). 生成器模式能帮助构建设计部件与表现的各 ...

  5. OC编程之道-接口适配之适配器

    已有的类与新的接口之间不兼容的问题相当普遍,人们已为它找到了一个解决方案.这个解决方案就是适配器. 1 何为适配器 what 适配器的主要作用是把被适配者的行为传递给管道另一端的客户端. 将一个类的接 ...

  6. Java并发编程75道面试题及答案

    1.在java中守护线程和本地线程区别? java中的线程分为两种:守护线程(Daemon)和用户线程(User). 任何线程都可以设置为守护线程和用户线程,通过方法Thread.setDaemon( ...

  7. Python灰帽子:黑客与逆向工程师的Python编程之道|百度网盘免费下载|新手黑客入门

    百度网盘免费下载:Python灰帽子:黑客与逆向工程师的Python编程之道 提取码:tgpg 目录  · · · · · · 第1章 搭建开发环境 11.1 操作系统要求 11.2 获取和安装Pyt ...

  8. PHP 面向对象编程和设计模式 (3/5) - 单例模式和工厂模式

    PHP高级程序设计 学习笔记 2014.06.11 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容 ...

  9. iOS书摘之Objective-C编程之道 iOS设计模式解析

    来自<Objective-C编程之道iOS设计模式解析>一书的摘要总结 一.Prototype 原型模式 定义:使用原型实例指定创建对象的种类,并通过复制这个原型创建新的对象.(<设 ...

随机推荐

  1. canvas缓动3

    这次缓动的是旋转旋转,写完之后才知道原来rotate是绕原点旋转,而且还带着rect本身的X与Y一起,所以我采用了translate达到位移效果,以免旋转到画布外面去,画完之后效果惨不忍睹,原来是忘记 ...

  2. datatable刷新表头

    使用jQuery的datatable生成表格数据,当需要改变表头时,调用Table.fnDestroy();再重新创建表头 var oTable = null; function initSettin ...

  3. Redis集群(四):主从配置二

    一.本文目的        主要介绍redis主从模式下各种情况 二.说明 主从的基本概念:Master用于写入,Slaver用于读取,不能写入或修改,一个Master可以对应多个Slaver Mas ...

  4. PHP "延迟静态绑定" 功能,static

    从这个名字的定义提取出两个关键点,第一点静态,也就是说这个功能只适用于静态属性或静态方法.第二点延迟绑定,这个根据下面代码就可以很好的理解 看一下这个例子: class A{ static $name ...

  5. CentOS 6.5安装在VMWare中Bridge模式下网卡eth0不能自动激活的问题

    VMWare 12.5.2 CentOS 6.5 basic VMWare网卡配置选择Bridge方式 问题: 默认情况下ifconfig命令只能看到网络设备lo,看不到eth0,也没有分配合理的IP ...

  6. SVN随记

    SVN中提交代码时报如下错误 commit -m "sync" E:/resource/rad_workspace/IMSCrawl/src/configuration.prope ...

  7. bzoj 1537: [POI2005]Aut- The Bus 线段树

    bzoj 1537: [POI2005]Aut- The Bus 先把坐标离散化 设f[i][j]表示从(1,1)走到(i,j)的最优解 这样直接dp::: f[i][j] = max{f[i-1][ ...

  8. Linux 查找文件并删除文件内容

    find * ./ |while read file; do echo ''>$file; done

  9. Java细粒度锁实现的3种方式

    最近在工作上碰见了一些高并发的场景需要加锁来保证业务逻辑的正确性,并且要求加锁后性能不能受到太大的影响.初步的想法是通过数据的时间戳,id等关键字来加锁,从而保证不同类型数据处理的并发性.而java自 ...

  10. 戴尔OMSA 使用指南

    戴尔的OMSA我们已经安装完成,但是没有web页面.因此我们目前想要看到服务器的相关硬件信息就需要使用命令行的方式获取了.那么,这里就介绍如何使用命令获取服务器硬件信息. 下面是我监控一些硬件信息的命 ...