用如下方法定义单例

@interface

singleton_interface(ClassName);

@end

实现单例在

@implemention

singleton_implemention(ClassName);

@end

 #define singleton_interface(class) + (instancetype)shared##class;
#define singleton_implementation(class)\
static class *_instance;\
\
+ (id)allocWithZone:(struct _NSZone *)zone \
{\
static dispatch_once_t onceToken;\
dispatch_once(&onceToken, ^{\
_instance = [[super allocWithZone:NULL] init];\
});\
\
return _instance;\
}\
\
+ (instancetype)shared##class \
{\
if(_instance == nil){\
_instance = [[class alloc] init];\
}\
\
return _instance;\
}\
\
- (id)copyWithZone:(struct _NSZone *)zone\
{\
return [class shared##class];\
}
 

但是 有时编译会出现错误:

duplicate symbol __instance in:

......class1.o

......class2.o

ld: 1 duplicate symbol for architecture x86_64

clang: error: linker command failed with exit code 1 (use -v to see invocation)

解决方法:

点击项目:

TARGETS-->Build Setting-->Apple LLVM 7.0 Code Generation -->No Common Blocks -->No

原因:我的理解,相同的代码块被两个类同时应用,commond + B build 时,编译器有时会误认为生成两个 目标文件是完全相同的。故而,要设置允许编译器识别有相同的代码块。实验:新建一个类 Director.h & Director.m,在 Director.h里导入Singleton.h

 #import <UIKit/UIKit.h>
#import "Singleton.h"
@interface Director : UIViewController
singleton_interface(Director);
@end

在Director.m里:

 #import "Director.h"

 @implementation Director
singleton_implementation(Director);
@end

再随便在新建一个类ViewController,在 viewController.h里导入Director.h

ViewController.h:

 #import "Director.h"

 @interface ViewController : UIViewController

 @end

ViewController.m

 #import "ViewController.h"

 @interface ViewController ()

 @end

 @implementation ViewController

 - (void)viewDidLoad {
[super viewDidLoad]; Director *d1 = [[Director alloc]init];
Director *d2 = [Director sharedDirector];
Director *d3 = [d1 copy]; NSLog(@"d1:%p\n,d2:%p\n,d3:%p",d1,d2,d3);
}

打印结果:地址完全一样

补充:

void dispatch_once( dispatch_once_t *predicate, dispatch_block_t block);其中第一个参数predicate函数,

dispatch_once_t 是一个predicate谓词,他约束后面的代码快在整个APP 里只被执行一次。而且该函数是GCD提供的线程安全的函数。

iOS 用宏定义写一个单例(Singleton)的更多相关文章

  1. 用 Java 写一个单例类?

    饿汉式单例 public class Singleton { private Singleton(){} private static Singleton instance = new Singlet ...

  2. 一个单例(Singleton),并说明单例的目的和好处

    单例的目的:保证一个类只有单一的实例,也就是说你无法通过new来创建这个类的一个新实例. 单例的好处:当一个对象在程序内部只能有一个实例的时候,它可以保证我们不会重复创建,而是始终指向同一个对象. S ...

  3. java 写一个单例设计程序,打印出该对象的地址

    class Test{ public static void main(String[] args) { singleton s1=singleton.getinstance(); singleton ...

  4. IOS 宏定义一个单例

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

  5. iOS 使用宏定义函数和代码块

    iOS使用宏定义函数和代码块 今天在开发过程中碰到一个问题:就是父类中要向外发送通知,然后子类中或者其他类中来接收它.当然一般是把它写到类方法中去,但是有个问题,就是如果调用的类不是它的子类,就不能直 ...

  6. iOS常用宏定义--实用

    在这里给大家分享一些常用的宏定义,喜欢的小伙伴可以直接在项目中使用(持续更新)!为了大家使用方便,请点击GitHub - 宏定义头文件下载 ! 1.获取屏幕宽度与高度 #define SCREEN_W ...

  7. C++实现一个单例模板类

    单例模式在项目开发中使用得比较多,一个单例的模板类显得很有必要,避免每次都要重复定义一个单例类型 //非多线程模式下的一个单例模板类的实现 // template_singleton.h #inclu ...

  8. java单链表的实现自己动手写一个单链表

    单链表:单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素.链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是 ...

  9. spring中如何向一个单例bean中注入非单例bean

    看到这个题目相信很多小伙伴都是懵懵的,平时我们的做法大都是下面的操作 @Component public class People{ @Autowired private Man man; } 这里如 ...

随机推荐

  1. AJAX 异步交互基本总结

    AJAX (Asynchronous JavaScript and Xml) 直译中文 - javascript和XML的异步 同步与异步的区别: 同步交互 执行速度相对比较慢 响应的是完整的HTML ...

  2. 归并排序(merge sort)

    M erge sort is based on the divide-and-conquer paradigm. Its worst-case running time has a lower ord ...

  3. 针对不同包之间的action跳转,怎么配置?

    例如一下的例子:两个包,如何跳转 <struts>           <constant name="struts.enable.DynamicMethodInvocat ...

  4. php 面向对象的方式访问数据库

    <body> <?php //面向对象的方式访问数据库 //造对象 $db = new MySQLi("localhost","root",& ...

  5. KVM中Linux虚拟机的硬盘添加方法

    [root@cache01 ~]# df -hT Filesystem Type Size Used Avail Use% Mounted on /dev/mapper/VolGroup-lv_roo ...

  6. (转)云存储:阿里云OSS 、又拍云和 七牛 的比较

    阿里OSS:好处就是,那是一套完整的体系,存储,数据库,CDN,服务器,阿里都可以给你全包.缺点,费用对于没有盈利的网站来说太高了,好像定位就是给那些高端客户使用的,而且CDN,OSS的流量是分开收费 ...

  7. 使用javascript的stack数据结构,实现进制转换

    function Stack() { var items = []; this.push = function(element){ items.push(element); } this.pop = ...

  8. sdut 2413:n a^o7 !(第三届山东省省赛原题,水题,字符串处理)

    n a^o7 ! Time Limit: 1000MS Memory limit: 65536K 题目描述 All brave and intelligent fighters, next you w ...

  9. js 默认行为取消

    js 默认行为取消   可以简单的  return false;   看需求吧 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transit ...

  10. 12、uwp 开发的零碎总结

    1.在给位 “修正版本号”(Major.Minor.Build.Revision)不能修改. 后, 商店上传失败,描述信息为:Apps are not allowed to have a Versio ...