Singleton模式iOS发展可能是其中最常用的模式中使用的。但是因为oc语言特性本身,想要写一个正确的Singleton模式是比较繁琐,iOS中单例模式的设计思路。

关于单例模式很多其它的介绍请參考这篇文章

单例顾名思义就是说一个类的实例仅仅能有一个。在java、C++这类语言中,能够通过将构造函数私有化来避免对象的反复创建。可是objective-c却不能够这样做,我们须要通过其它机制来达到这个目的。普通情况下,可能我们写的单例模式是这种:

#import <Foundation/Foundation.h>

@interface Singleton : NSObject

+(instancetype) shareInstance ;

@end

#import "Singleton.h"

@implementation Singleton

static Singleton* _instance = nil;

+(instancetype) shareInstance
{
static dispatch_once_t onceToken ;
dispatch_once(&onceToken, ^{
_instance = [[self alloc] init] ;
}) ; return _instance ;
} @end

详细使用:

#import <Foundation/Foundation.h>
#import "Singleton.h" int main(int argc, const char * argv[]) {
@autoreleasepool { Singleton* obj1 = [Singleton shareInstance] ;
NSLog(@"obj1 = %@.", obj1) ; Singleton* obj2 = [Singleton shareInstance] ;
NSLog(@"obj2 = %@.", obj2) ; //
Singleton* obj3 = [[Singleton alloc] init] ;
NSLog(@"obj3 = %@.", obj3) ;
}
return 0;
}

输出结果为 :

2014-12-15 16:06:28.344 ObjcSingleton[8847:303] obj1 = <Singleton: 0x1001086e0>.
2014-12-15 16:06:28.346 ObjcSingleton[8847:303] obj2 = <Singleton: 0x1001086e0>.
2014-12-15 16:06:28.346 ObjcSingleton[8847:303] obj3 = <Singleton: 0x100103940>.

能够看到。当我们调用shareInstance方法时获取到的对象是相同的,可是当我们通过alloc和init来构造对象的时候。得到的对象却是不一样的。

那么问题就来了。我们通过不同的途径得到不同的对象,显然是不行的。我们必须要确保对象的唯一性,所以我们就须要封锁用户通过alloc和init以及copy来构造对象这条道路。

我们知道,创建对象的步骤分为申请内存(alloc)、初始化(init)这两个步骤,我们要确保对象的唯一性,因此在第一步这个阶段我们就要拦截它。

当我们调用alloc方法时,oc内部会调用allocWithZone这种方法来申请内存。我们覆写这种方法,然后在这种方法中调用shareInstance方法返回单例对象,这样就能够达到我们的目的。拷贝对象也是相同的原理,覆写copyWithZone方法,然后在这种方法中调用shareInstance方法返回单例对象。看代码吧:

#import "Singleton.h"

@implementation Singleton

static Singleton* _instance = nil;

+(instancetype) shareInstance
{
static dispatch_once_t onceToken ;
dispatch_once(&onceToken, ^{
_instance = [[super allocWithZone:NULL] init] ;
}) ; return _instance ;
} +(id) allocWithZone:(struct _NSZone *)zone
{
return [Singleton shareInstance] ;
} -(id) copyWithZone:(struct _NSZone *)zone
{
return [Singleton shareInstance] ;
} @end

再看看效果怎样:

main : 

#import <Foundation/Foundation.h>
#import "Singleton.h" int main(int argc, const char * argv[]) {
@autoreleasepool { Singleton* obj1 = [Singleton shareInstance] ;
NSLog(@"obj1 = %@.", obj1) ; Singleton* obj2 = [Singleton shareInstance] ;
NSLog(@"obj2 = %@.", obj2) ; //
Singleton* obj3 = [[Singleton alloc] init] ;
NSLog(@"obj3 = %@.", obj3) ; Singleton* obj4 = [[Singleton alloc] init] ;
NSLog(@"obj4 = %@.", [obj4 copy]) ;
}
return 0;
}

输出结果:

2014-12-15 16:11:24.734 ObjcSingleton[8979:303] obj1 = <Singleton: 0x100108720>.
2014-12-15 16:11:24.735 ObjcSingleton[8979:303] obj2 = <Singleton: 0x100108720>.
2014-12-15 16:11:24.736 ObjcSingleton[8979:303] obj3 = <Singleton: 0x100108720>.
2014-12-15 16:11:24.736 ObjcSingleton[8979:303] obj4 = <Singleton: 0x100108720>.

能够看到获取到的对象都是一样的了。

思路就是这样。假设有更为严格的措词请留言,通知。谢谢~

版权声明:本文Mr.Simple原创文章,不得未经同意转载。

Objective-c正确的写法单身的更多相关文章

  1. JavaScript函数setInterval()和setTimeout()正确的写法

    一.常规写法 1.1 不传参数 function a (x, y) { var i = 0; var b = function(){ console.log((x * y) + (i++)); } r ...

  2. 正确robots写法,解决百度搜索不显示缩略图问题

    网站上线http://zhimo.yuanzhumuban.cc/有一年左右时间了,百度搜索显示略缩图少之又少,通过自己这几天的观察发现. 结合百度站长平台的 robots 工具和抓取诊断工具检查后, ...

  3. 使用runloop阻塞线程的正确写法

    使用runloop阻塞线程的正确写法 runloop可以阻塞线程,等待其他线程执行后再执行. 比如: @implementation ViewController{    BOOL end;}…– ( ...

  4. nodejs读取文件时相对路径的正确写法(使用fs模块)

    在开发nodejs中,我们往往需要读取文件或者写入文件,最常用的模块就是fs核心模块.一个最简单的写入文件的代码如下(暂时不考虑回调函数): fs.readFile("./test.txt& ...

  5. js自执行函数的几种不同写法的比较

    经常需要一个函数自执行,可惜这一种写法是错的: function(){alert(1);}();  原因是前半段“function(){alert(1);}”被当成了函数声明,而不是一个函数表达式,从 ...

  6. iBatis 中 Like 的写法实现模糊查询

    iBatis 开发指南告诉我们,当 Person 对象的 name 属性不为 null 时启用 name 查询条件在映射文件 person.xml 中的配置为 <select id=" ...

  7. location.href跳转不正确

    今天写这个随笔的用意是为了记录我遇到的一种情况,导致我页面无法正确跳转 location.href跳转页面其实很简单,只要附上url就可以了,但是今天我在测试一个跳转时是这么写的: location. ...

  8. 如何进行正确的SQL性能优化

    在SQL查询中,为了提高查询的效率,我们常常采取一些措施对查询语句进行SQL性能优化.本文我们总结了一些优化措施,接下来我们就一一介绍. 1.查询的模糊匹配 尽量避免在一个复杂查询里面使用 LIKE ...

  9. java web 资源地址写法

    前提:假设web应用test(工程名) webapps下面有一资源文件test.html 规则:在获取资源时一般使用的是相对路径,以符号/开头,而 / 代表什么取决于这个地址给谁使用.服务器使用时,/ ...

随机推荐

  1. .NET开发必看资料53个+经典源码77个

    目录0豆下载:http://down.51cto.com/data/426019 附件预览: 基于.net构架的留言板项目大全源码 http://down.51cto.com/zt/70 ASP.ne ...

  2. Cocos2D &amp; SpriteBuilder Developer Guide

    https://www.makegameswith.us/docs/#!/cocos2d/1.0/overview

  3. android2.2应用开发之IccCard(sim卡或USIM卡)

    tyle="margin:20px 0px 0px; font-size:14px; line-height:26px; font-family:Arial; color:rgb(51,51 ...

  4. VMware WorkStation安装时提示The MSI failed

    以前安装过其他版本的VMware workstation卸载不完全造成的 先把所有VMware相关服务关闭,然后打开注册表,搜索所有VMware相关键值,删除掉,然后再安装就可以了 前提是你机器上没有 ...

  5. leetcode第一刷_Convert Sorted List to Binary Search Tree

    好,二叉搜索树粉末登场,有关他的问题有这么几个,给你一个n,如何求全部的n个节点的二叉搜索树个数?能不能把全部的这些二叉搜索树打印出来? 这道题倒不用考虑这么多,直接转即可了,我用的思想是分治,每次找 ...

  6. Objective-C类的使用

    Objective-C教程的例题: // // main.m // test // // Created by liwei on 14-10-28. // Copyright (c) 2014年 li ...

  7. hash表、hash算法

    概念: 散列表(Hash table.也叫哈希表),是依据关键码值(Key value)而直接进行訪问的数据结构. 也就是说,它通过把关键码值映射到表中一个位置来訪问记录,以加快查找的速度.这个映射函 ...

  8. key 串口

    /******************************************************************** 函数功能:往串口发送一字节数据(可通过超级终端或者串口调试助 ...

  9. JS伪3D 图形透视效果

    本文地址:http://blog.csdn.net/ei__nino/article/details/9243331 本来是想实现多个圆片的透视效果,对于运算都是测试得出的.不是严谨的数学计算. 使用 ...

  10. Android 高仿微信即时聊天 百度云为基础的推

    转载请注明出处:http://blog.csdn.net/lmj623565791/article/details/38799363 ,本文出自:[张鸿洋的博客] 一直在仿微信界面,今天最终有幸利用百 ...