用如下方法定义单例
@interface
singleton_interface(ClassName);
@end
实现单例在
@implemention
singleton_implemention(ClassName);
@end
1 #define singleton_interface(class) + (instancetype)shared##class; 2 #define singleton_implementation(class) 3 static class *_instance; 4 5 + (id)allocWithZone:(struct _NSZone *)zone 6 { 7 static dispatch_once_t onceToken; 8 dispatch_once(&onceToken, ^{ 9 _instance = [[super allocWithZone:NULL] init]; 10 }); 11 12 return _instance; 13 } 14 15 + (instancetype)shared##class 16 { 17 if(_instance == nil){ 18 _instance = [[class alloc] init]; 19 } 20 21 return _instance; 22 } 23 24 - (id)copyWithZone:(struct _NSZone *)zone 25 { 26 return [class shared##class]; 27 }
但是 有时编译会出现错误:
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
1 #import <UIKit/UIKit.h> 2 #import "Singleton.h" 3 @interface Director : UIViewController 4 singleton_interface(Director); 5 @end
在Director.m里:
1 #import "Director.h" 2 3 @implementation Director 4 singleton_implementation(Director); 5 @end
再随便在新建一个类ViewController,在 viewController.h里导入Director.h
ViewController.h:
1 #import "Director.h" 2 3 @interface ViewController : UIViewController 4 5 6 @end
ViewController.m
1 #import "ViewController.h" 2 3 @interface ViewController () 4 5 @end 6 7 @implementation ViewController 8 9 - (void)viewDidLoad { 10 [super viewDidLoad]; 11 12 Director *d1 = [[Director alloc]init]; 13 Director *d2 = [Director sharedDirector]; 14 Director *d3 = [d1 copy]; 15 16 NSLog(@"d1:%p ,d2:%p ,d3:%p",d1,d2,d3); 17 }
打印结果:地址完全一样
补充:
void dispatch_once( dispatch_once_t *predicate, dispatch_block_t block);其中第一个参数predicate函数,
dispatch_once_t 是一个predicate谓词,他约束后面的代码快在整个APP 里只被执行一次。而且该函数是GCD提供的线程安全的函数。