zoukankan      html  css  js  c++  java
  • iOS 用宏定义写一个单例(Singleton)

    用如下方法定义单例

    @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提供的线程安全的函数。 

  • 相关阅读:
    测试用例设计白皮书--测试用例设计综合策略
    流程控制
    与用户交互,格式化输出,基本运算符
    jupyter的安装
    python程序运行的方式、变量、注释、内存管理、数据类型
    博客园 文章爬取(乱写的,有的爬不下来)
    Python 九九乘法表打印
    Python 爬歌曲
    redis快速入门
    UDPsocket编程
  • 原文地址:https://www.cnblogs.com/wjw-blog/p/5614225.html
Copyright © 2011-2022 走看看