//Singleton.h

// 以后就可以使用interfaceSingleton来替代后面的方法声明。    \表示下一行也是上一行的内容。

#define interfaceSingleton(name)  +(instancetype)share##name

#if __has_feature(objc_arc)

//ARC编译这段

#define implementationSingleton(name)  \
+ (instancetype)share##name \
{ \
name *instance = [[self alloc] init]; \
return instance; \
} \
static name *_instance = nil; \
+ (instancetype)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [[super allocWithZone:zone] init]; \
}); \
return _instance; \
} \
- (id)copyWithZone:(NSZone *)zone{ \
return _instance; \
} \
- (id)mutableCopyWithZone:(NSZone *)zone \
{ \
return _instance; \
}
#else // MRC,编译这段。 #define implementationSingleton(name) \
+ (instancetype)share##name \
{ \
name *instance = [[self alloc] init]; \
return instance; \
} \
static name *_instance = nil; \
+ (instancetype)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [[super allocWithZone:zone] init]; \
}); \
return _instance; \
} \
- (id)copyWithZone:(NSZone *)zone{ \
return _instance; \
} \
- (id)mutableCopyWithZone:(NSZone *)zone \
{ \
return _instance; \
} \
- (oneway void)release \
{ \
} \
- (instancetype)retain \
{ \
return _instance; \
} \
- (NSUInteger)retainCount \
{ \
return MAXFLOAT; \
}
#endif
//
// Tools.h #import <Foundation/Foundation.h>
#import "Singleton.h" @interface Tools : NSObject<NSCopying, NSMutableCopying> // share + 当前的类名
//+ (instancetype)shareTools; interfaceSingleton(Tools); ////用Singleton.h里面的内容替换。 @end
//
// Tools.m #import "Tools.h" @implementation Tools /*
+ (instancetype)shareTools
{
Tools *instance = [[self alloc] init];
return instance;
} static Tools *_instance = nil;
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[super allocWithZone:zone] init];
});
return _instance;
} - (id)copyWithZone:(NSZone *)zone{ return _instance;
} - (id)mutableCopyWithZone:(NSZone *)zone
{
return _instance;
} // MRC
- (oneway void)release
{ } - (instancetype)retain
{
return _instance;
} - (NSUInteger)retainCount
{
return MAXFLOAT;
}
*/ implementationSingleton(Tools) ////用Singleton.h里面的内容替换。 @end
//
// Person.h
// #import <Foundation/Foundation.h>
#import "Singleton.h" @interface Person : NSObject interfaceSingleton(Person); ////用Singleton.h里面的内容替换。 @end
//
// Person.m #import "Person.h" @implementation Person implementationSingleton(Person) //用Singleton.h里面的内容替换。 @end
//
// main.m
// 宏定义抽取单例,宏定义本质是替换,简化代码,用公用的代码进行替换。
// #import <Foundation/Foundation.h>
#import "Tools.h"
#import "Person.h" int main(int argc, const char * argv[]) { Tools *t1 = [[Tools alloc] init]; //内部会调用allocWithZone
Tools *t2 = [Tools new];// [[alloc] init] allocWithZone
Tools *t3 = [Tools shareTools]; Tools *t4 = [t3 copy];
Tools *t5 = [t3 mutableCopy]; NSLog(@"%p, %p, %p, %p, %p", t1, t2, t3, t4, t5);//0x100300120, 0x100300120, 0x100300120, 0x100300120, 0x100300120 Person *p1 = [Person sharePerson];
Person *p2 = [Person sharePerson];
Person *p3 = [Person sharePerson]; NSLog(@"%p, %p, %p", p1 , p2, p3);//0x100202460, 0x100202460, 0x100202460 // 如何判断当前是ARC还是MRC?
// 可以在编译的时候判断当前是否是ARC
#if __has_feature(objc_arc)
NSLog(@"ARC");
#else
NSLog(@"MRC");
#endif
return ;
}

oc85--利用宏定义简化单例的更多相关文章

  1. c++中利用宏定义简化for循环使用

    话不多说,上方法 #define _for(i,a,b) for( int i=(a); i<(b); ++i) #define _rep(i,a,b) for( int i=(a); i< ...

  2. IOS 宏定义一个单例

    有时候是不是因为频繁地创建一个单例对象而头疼,一种方式要写好多遍?当然你可以用OC语言进行封装.但下面将介绍一种由C语言进行的封装.只要实现下面的方法,以后建单例对象只要二句话. 1.新建一个.h文件 ...

  3. 指针直接赋值为整型AND利用宏定义求结构体成员偏移量

    首先我们要更正一个很熟悉的概念,那就是指针不仅仅是“地址”,指针还有一个很重要的特性,那就是“类型”. 指针初始化时,“=”的右操作数; 除外,该语句表示指针为空): 所以 ; 这样的代码是不允许的. ...

  4. iOS下单例模式实现(二)利用宏定义快速实现

    在上一节里提到了用利用gcd快速实现单例模式. 一个项目里面可能有好几个类都需要实现单例模式.为了更高效的编码,可以利用c语言中宏定义来实现. 新建一个Singleton.h的头文件. // @int ...

  5. 【scala】类的定义和单例对象

    一.类的定义 Scala类的定义跟JAVA中类的定义基本是一样的. 示例 class ChecksumAccumulator{ var sum = 0;//Scala默认关键字为public priv ...

  6. 利用宏定义实现C++程序在Unix和Win32环境下的通用性

    [转] 1.1. 宏定义软件的代码,从跨平台的角度来看,可以分为平台相关的和平台无关的.采用C/C++编写的软件,在进行移植时,平台无关的的代码基本上不需要做大的改动,但平台相关的代码需要做很大的调整 ...

  7. 利用宏定义令iOS项目当中的NSLog不执行

    今天在博客园主页看到一篇帖子,提到NSLog消耗运行时性能: http://www.cnblogs.com/sunnyxx/p/3680623.html 解决方案如下,在​Prefix.pch文件当中 ...

  8. Excel—在Excel中利用宏定义实现MD5对字符串(如:手机号)或者文件加密

    下载宏文件[md5宏] 加载宏 试验md5加密 可能遇到的问题 解决办法 下载宏文件[md5宏] 下载附件,解压,得md5宏.xla md5宏.zip 加载宏 依次打开[文件]-[选项]-[自定义功能 ...

  9. OC-copy,单例

    总结 编号 主题 内容 一 NSFileManager NSFileManager介绍/用法(常见的判断)/文件访问/文件操作 二 集合对象的内存管理 集合对象的内存管理/内存管理总结 三 *copy ...

随机推荐

  1. dutacm.club_1094_等差区间_(线段树)(RMQ算法)

    1094: 等差区间 Time Limit:5000/3000 MS (Java/Others)   Memory Limit:163840/131072 KB (Java/Others)Total ...

  2. Java_数组1_16.5.12

    声明整型数组a: int[] a; 这时,只声明了变量a,还应该使用new运算符创建数组: int[] a=new int [100];(数组长度不要求是一个常量:new int[n]会创建一个长度为 ...

  3. CAD利用Select2得到所有实体(网页版)

    主要用到函数说明: IMxDrawSelectionSet::Select2 构造选择集.详细说明如下: 参数 说明 [in] MCAD_McSelect Mode 构造选择集方式 [in] VARI ...

  4. 日常开发需要掌握的Git命令

    本人待的两家公司,一直都是用的SVN,Git我只是自己私下学习和开发小项目的时候用过,工作一直没有使用过,但还是要学的... Git是最好的分布式版本控制系统 工作流程 SVN和Git的区别 SVN是 ...

  5. <MyBatis>入门二 全局配置文件

    <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC ...

  6. Python学习-算术运算符,赋值运算符和复合运算符

    算术运算符 常见的算术运算符有 : +     加法运算符 print(1 + 2); // 3 print('1' + '2'); //12 不仅可以进行2个数字的相加,还可以连接2个字符串 -   ...

  7. mac下用crontab实现pytho3脚本自动定期执行,包括scrapy的定期执行

    呃 其实要明天上午才能知道是否成功,毕竟改了一个小参数的. 首先,来学两个小命令: step1: $ sudo crontab -e step2: # 然后提示password输入密码,即可进入编辑页 ...

  8. 洛谷 1821 [USACO07FEB]银牛派对Silver Cow Party

    [题解] 其实解法 #include<cstdio> #include<cstring> #include<algorithm> #define LL long l ...

  9. Java MyBatis 插入数据库返回主键--insertSelective这样就不用每次到数据库里面查询了

    insertSelective---Java MyBatis 插入数据库返回主键--insertSelective这样就不用每次到数据库里面查询了 https://www.cnblogs.com/xi ...

  10. Stones HDU 1896

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1896 题目大意: 有n个石头,每个石头有:p  它所在的位置 ,d  它能扔多远 从0 开始,遇到第奇 ...