博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS开发-单例模式
阅读量:5900 次
发布时间:2019-06-19

本文共 2953 字,大约阅读时间需要 9 分钟。

单例模式是一种非常常见的设计模式,之前文章中UIApplication就是一种典型的单例模式,单例理解起来叶很简单,就不是不管如果访问始终只有一个实例化对象,定义全局共享的变量,如果对象是空则初始化一个对象,如果对象已经存在则使用已经实例化的对象。单例设计模式的作用是使得这个类的一个对象成为系统中的唯一实例,因此需要用一种唯一的方法去创建这个对象并返回这个对象的地址。下面有一张苹果官网的图片可以参考一下:

定义一个Food类,大家共享同一个食物,定义一个静态变量,一个实例方法:

static Food *sharedFoodObj=nil;+(Food *)sharedFood{    if (!sharedFoodObj) {        sharedFoodObj=[[Food alloc]init];    }    return sharedFoodObj;}

 执行以下代码,最后发现两个实例对象food和foodNext地址是一样的: 

Food  *food=[Food sharedFood];    Food  *foodNext=[Food sharedFood];    NSLog(@"共享地址:%p-共享地址:%p",food,foodNext);

 如果每次都遵守规则调用sharedFood方法,单例模式算是完成了,但是对象是可以实例化的,看一段下面的代码:

Food  *food=[Food sharedFood];    Food  *foodInit=[[Food alloc]init];    NSLog(@"共享地址:%p-实例地址:%p",food,foodInit);

 food和foodInit的地址是不一样,这个时候我们需要动手改造以下改成的方法,让实例化对象的出来的地址也是一样的,这个时候需要重写allocWithZone方法:

+(Food *)sharedFood{    if (!sharedFoodObj) {        sharedFoodObj=[[super allocWithZone:NULL]init];    }    return sharedFoodObj;}+(instancetype)allocWithZone:(struct _NSZone *)zone{    return [self sharedFood];}

 如果对象拷贝的时候也需要是同一对象的话,可以加一个方法:

+(id)copyWithZone:(struct _NSZone *)zone{    return [self sharedFood];}

如果为了确保多线程情况下,仍然确保实体的唯一性,这个时候可以加上@synchronized,@synchronized的作用是创建一个互斥锁,保证此时没有其它线程对self对象进行修改。这个是objective-c的一个锁定令牌,防止self对象在同一时间内被其它线程访问,起到线程的保护作用。单例模式或者操作类的static变量中使用比较多。当两个并发线程访问同一个对象@synchronized(self)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。

+(Food *)sharedFood{    @synchronized(self){        if (!sharedFoodObj) {            sharedFoodObj=[[Food alloc]init];        }    }    return sharedFoodObj;}

 苹果Mac OS 10.6和iOS4.0后引入了GCD,利用GCD(Grand Central Dispatch)和ARC(Automatic Reference Counting)实现单例,这个时候我们可以通过dispatch_once简单的实现,代码如下:

+ (instancetype)sharedInstance{    static Food *sharedFoodObj = nil;    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        sharedFoodObj =[[super allocWithZone:NULL]init];    });        return sharedFoodObj;}

Food.m中的代码:

////  Food.m//  Demo//http://www.cnblogs.com/xiaofeixiang//  Created by keso on 15/2/8.//  Copyright (c) 2015年 keso. All rights reserved.//#import "Food.h"@implementation Foodstatic Food *sharedFoodObj=nil;+(Food *)sharedFood{    if (!sharedFoodObj) {        sharedFoodObj=[[super allocWithZone:NULL]init];    }    return sharedFoodObj;}//+(id)copyWithZone:(struct _NSZone *)zone{    return [self sharedFood];}- (id)copyWithZone:(NSZone *)zone{    return self;}+ (instancetype)sharedInstance{    static Food *sharedFoodObj = nil;    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        sharedFoodObj =[[super allocWithZone:NULL]init];    });        return sharedFoodObj;}+(instancetype)allocWithZone:(struct _NSZone *)zone{    return [self sharedInstance];}@end

 iOS的单例通过以上方式可以实现,网上有些文章实现单例用了七个方法,不过自从有了ARC之后,有些方法Apple已经不需要重写,说一个题外话,昨天有个博客园的园友只字不改抄袭了我的文章,文章下面说明栏也说明过了(博客经个人辛苦努力所得,如有转载会特别申明,博客不求技惊四座,但求与有缘人分享个人学习知识,生活学习提高之用),本人是自己辛苦所得,抄袭转载麻烦留一个链接,技术文章技术人看,做一个技术人需要有些底线~

转载于:https://www.cnblogs.com/xiaofeixiang/p/4280182.html

你可能感兴趣的文章
Docker简易版:使用更少击键运行Redis,MongoDB
查看>>
laravel框架快速入门(一)
查看>>
swing 鼠标监听addMouseMotionListener
查看>>
js如何实现10秒倒计
查看>>
ubuntu下解决鼠标滚轮不能使用的问题
查看>>
隐马尔可夫(HMM)、前/后向算法、Viterbi算法 再次总结
查看>>
LAV Filters
查看>>
iOS11 automaticallyAdjustsScrollViewInsets和estimatedRowHeight适配
查看>>
订阅linux kernel的mail list
查看>>
mysql 批量更新多条记录(且不同值)的实现方法
查看>>
Hadoop上路_02-hadoop介绍和环境准备
查看>>
JFinal多参数搜索条件自动组装及参数传递
查看>>
c++ ios_base register_callback方法使用
查看>>
Java中为什么需要Object类,Object类为什么是所有类的父类
查看>>
css3 -webkit-flex 布局
查看>>
大数据Benchmark
查看>>
windows server2008多用户远程登陆设置方法
查看>>
sencha touch巧妙使用请求超时提升用户体验
查看>>
15. 3Sum
查看>>
ArrayList源码解析
查看>>