用GCD写Objective-c的单例模式和C#有比较大的区别

声明h文件

#import <Foundation/Foundation.h>

@interface me : NSObject<NSObject>
@property (nonatomic) NSInteger age;
+(instancetype)makeme;
@end

instancetype和id的区别

instancetype返回的是该实例类型,而id返回的是未知类型

①instancetype可以返回和方法所在类相同类型的对象,id只能返回未知类型的对象,便于编写调试

②instancetype只能作为返回值,不能像id那样作为参数

具体原理是利用dispatch_once 来创建一个单实例,因为该函数在程序生命周期内只运行一次

void dispatch_once( dispatch_once_t *predicate, dispatch_block_t block);

第一个参数是检查后面第二个参数所代表的代码块是否被调用的谓词,第二个参数是在整个应用程序中只会被调用一次的代码块。

不过众多的dispath_once版本中我认为这个下面这个还不错

#import "me.h"
static me *myself;
@implementation me
+(id)allocWithZone:(struct _NSZone *)zone{
static dispatch_once_t onetaken;
dispatch_once(&onetaken,^{
myself=[super allocWithZone:zone];
});
return myself;
}
+(instancetype)makeme{
static dispatch_once_t onetaken;
dispatch_once(&onetaken, ^{
myself=[[self alloc]init];
});
return myself;
}
-(id)copy{
return myself;
}

这里我们需要弄清楚allocWithZone方法。oc对象的初始化是alloc和init配合。alloc划分内存,init为实例配置参数变量,如对比下面代码,我删除了allocWithZone方法

#import "me.h"
static me *myself;
@implementation me
+(instancetype)makeme{
static dispatch_once_t onetaken;
dispatch_once(&onetaken, ^{
myself=[[self alloc]init];
});
return myself;
}

下面的例子是如果你如果用了

me *myself=[[me alloc]init];
me *myself1=[me makeme];

你会发现你获得了一个新的实例,。。。myself和myself1是不同的,这货不是单实例。。。当然因为我们用的alloc+init方法已经绕过了dispath_once的方法,单实例也就失效了

这意味着我们需要从实例初始化的地方开始

查看allocWithZone方法的介绍是

使用alloc方法初始化一个类的实例的时候,默认是调用了 allocWithZone 的方法。于是我们可以把这个也堵上就即使用户使用alloc +init 也不会产生新的实例。

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

  1. Automake

    Automake是用来根据Makefile.am生成Makefile.in的工具 标准Makefile目标 'make all' Build programs, libraries, document ...

  2. 从Objective-C到Swift 单例模式

    在Objective-C中经常会用到单例模式.最常见的就是: [UIApplication sharedApplication].delegate 这里的sharedApplication就是一个返回 ...

  3. Design Patterns Simplified - Part 2 (Singleton)【设计模式简述--第二部分(单例模式)】

    原文链接: http://www.c-sharpcorner.com/UploadFile/19b1bd/design-patterns-simplified-part-2-singleton/ De ...

  4. iOS开发核心语言Objective C —— 全部知识点总结

    本分享是面向有意向从事iOS开发的伙伴及苹果产品的发烧友,亦或是已经从事了iOS的开发人员,想进一步提升者.假设您对iOS开发有极高的兴趣,能够与我一起探讨iOS开发.一起学习,共同进步.假设您是零基 ...

  5. Objective-C在ARC下结合GCD的单例模式和宏模版

    单例模式在iOS开发过程中经常用到,苹果提供过objective c单例的比较官方的写法: static MyGizmoClass *sharedGizmoManager = nil; + (MyGi ...

  6. C++实现线程安全的单例模式

    在某些应用环境下面,一个类只允许有一个实例,这就是著名的单例模式.单例模式分为懒汉模式,跟饿汉模式两种. 首先给出饿汉模式的实现 template <class T> class sing ...

  7. 23种设计模式--单例模式-Singleton

    一.单例模式的介绍 单例模式简单说就是掌握系统的至高点,在程序中只实例化一次,这样就是单例模式,在系统比如说你是该系统的登录的第多少人,还有数据库的连接池等地方会使用,单例模式是最简单,最常用的模式之 ...

  8. angular2系列教程(十)两种启动方法、两个路由服务、引用类型和单例模式的妙用

    今天我们要讲的是ng2的路由系统. 例子

  9. java设计模式之--单例模式

    前言:最近看完<java多线程编程核心技术>一书后,对第六章的单例模式和多线程这章颇有兴趣,我知道我看完书还是记不住多少的,写篇博客记录自己所学的只是还是很有必要的,学习贵在坚持. 单例模 ...

  10. 设计模式C#合集--单例模式

    单例模式 代码: 第一种: private static Singleton singleton = null; private Singleton() { } public static Singl ...

随机推荐

  1. 【Excle】Countif函数

    Countif在Excle中是相当的使用,那么我们看下Countif的如下几个功能: ①一对一对比两列数据 ②输入时必须指定包含指定字符 ③帮助Vlookup实现一对多查找 ④统计不重复的个数 一对一 ...

  2. WPF中Auto与*的差别

    Auto 表示自己主动适应显示内容的宽度, 如自己主动适应文本的宽度,文本有多长,控件就显示多长. * 则表示按比例来分配宽度. <ColumnDefinition Width="3* ...

  3. (四)EasyUI 使用——form表单2 & window窗口

    form表单组件主要有以下内容(如下图)      6. progressbar进度条  每隔1秒让进度条按随机数填充,直至充满进度条刻度(只能执行一次) 进度条: <div id=" ...

  4. es number_of_shards和number_of_replicas

    number_of_replicas 是数据备份数,如果只有一台机器,设置为0 number_of_shards  是数据分片数,默认为5,有时候设置为3 可以在线改所有配置的参数,number_of ...

  5. rsync for windows 详细使用教程

    rsync for windows 详细使用教程内容简介:rsync在windows与windows服务器之间的同步设置 1.准备两台机器: server-----192.168.0.201 clie ...

  6. unity, get Canvas Scaler referenceResolution

    需要using UnityEngine.UI; 然后就可以访问到CanvasScaler组件. float width=GetComponent<CanvasScaler> ().refe ...

  7. MySQL 慢查询日志(Slow Query Log)

    同大多数关系型数据库一样.日志文件是MySQL数据库的重要组成部分.MySQL有几种不同的日志文件.通常包含错误日志文件,二进制日志,通用日志.慢查询日志.等等.这些日志能够帮助我们定位mysqld内 ...

  8. C# Type.GetConstructor() 根据构造函数参数获取实例对象(一)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  9. mybatis执行多条sql语句

    1,mybatis执行多条sql语句,有以下几种思路, a,存储过程 b,修改jdbc的参数,允许执行多条语句,如下所示: sqlserver可以直接使用begin,end来执行多条语句, mysql ...

  10. IDEA中maven打包跳过Junit Test

    运行MVN install时需要跳过Junit的test cases,可以采用下面的方法: mvn install -DskipTests 或者mvn install -Dmaven.test.ski ...