在iOS中使用宏寫單例

vb013933 8年前發布 | 6K 次閱讀 iOS開發 移動開發

本文只介紹ARC情況下的單利

過去一直背不下來單利如何寫,就是知道這么回事,也知道通過宏來寫單利,但是一直記不住,今天就來記錄一下

- (void)viewDidLoad {
    [super viewDidLoad];
    SIPerson *person = [[SIPerson alloc] init];
    NSLog(@"%@",person);

    SIPerson *person1 = [[SIPerson alloc] init];
    NSLog(@"%@",person1);

}

創建person,打印,實際上是2個對象。沒毛病.

創建方法

#import "SIPerson.h"

static SIPerson *instance_ = nil;
@implementation SIPerson
///方法1,快速創建對象
+ (instancetype)sharedInstance{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance_ = [[self alloc] init];
    });
    return instance_;
}

///方法2.這個方法一定要有,就是alloc] init]方法,一定會調用這個方法
+ (instancetype)allocWithZone:(struct _NSZone *)zone{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance_ = [super allocWithZone:zone];
    });
    return instance_;
}
@end
//此處還應該有一個+ copy方法,因為可能是copy,那么有可能是生成新的方法

方法12都要實現,才能是單利。假如方法2沒有實現,通過 sharedInstance 實現的確實是一個單利,但是通過 alloc] init] 有生成了另一個對象

2016-09-17 14:17:45.086 SharedInstance[9158:611161] <SIPerson: 0x7f9ab260bfe0>
2016-09-17 14:17:45.087 SharedInstance[9158:611161] <SIPerson: 0x7f9ab2686da0>

如果你的對象將來可能還要調用 copy (應該聲明<NSCopying>協議),那么你應該還要實現一個方法

- (id)copyWithZone:(NSZone *)zone{
    return instance_;
}

copy的時候,一般是生成了一個新的對象,所以不是單利了,但是用的時候比較少,不是特別需要的,可以不實現這個方法,為毛要這樣去寫?因為他是對象方法, instance_ 里面有值

[super viewDidLoad];
    SIPerson *person = [SIPerson sharedInstance];
    NSLog(@"%@",person);

    SIPerson *person1 = [[SIPerson alloc] init];
    NSLog(@"%@",person1);    

    SIPerson *person2 = [person1 copy];
    NSLog(@"%@",person2);

結果如下

2016-09-17 14:24:10.555 SharedInstance[9199:615987] <SIPerson: 0x7f8302d07050>
2016-09-17 14:24:10.555 SharedInstance[9199:615987] <SIPerson: 0x7f8302d07050>
2016-09-17 14:24:10.556 SharedInstance[9199:615987] <SIPerson: 0x7f8302d07050>

新建文件的步驟

/**
 *  在.h文件中定義的宏,arc
 *
 *  SISingletonH(name) 這個是宏
 *  + (instancetype)shared##name;這個是被代替的方法, ##代表著shared+name 高度定制化
 * 在外邊我們使用 “SISingletonH(gege)” 那么在.h文件中,定義了一個方法"+ (instancetype)sharedgege",所以,第一個字母要大寫
 *
 *  @return 一個搞定好的方法名
 */
#define SISingletonH(name) + (instancetype)shared##name;


/**
 *  在.m文件中處理好的宏 arc
 *
 *  SISingletonM(name) 這個是宏,因為是多行的東西,所以每行后面都有一個"\",最后一行除外,
 * 之所以還要傳遞一個“name”,是因為有個方法要命名"+ (instancetype)shared##name"
 *  @return 單利
 */
#define SISingletonM(name) \
static SIPerson *instance_ = nil;\
+ (instancetype)shared##name{\
    static dispatch_once_t onceToken;\
    dispatch_once(&onceToken, ^{\
        instance_ = [[self alloc] init];\
    });\
    return instance_;\
}\
+ (instancetype)allocWithZone:(struct _NSZone *)zone{\
    static dispatch_once_t onceToken;\
    dispatch_once(&onceToken, ^{\
        instance_ = [super allocWithZone:zone];\
    });\
    return instance_;\
}\
- (id)copyWithZone:(NSZone *)zone{\
    return instance_;\
}

實際使用

//.h文件
SISingletonH(Default)
//.m文件
SISingletonM(Default)

都是一句話,都沒有符號(定義的時候就給了符號),就這么簡單

在實際使用的時候

[super viewDidLoad];
    SIPerson *person = [SIPerson sharedDefault];
    NSLog(@"%@",person);

    SIPerson *person1 = [[SIPerson alloc] init];
    NSLog(@"%@",person1);

    SIPerson *person2 = [person1 copy];
    NSLog(@"%@",person2);

//打印結果
2016-09-17 14:56:39.508 SharedInstance[9292:633076] <SIPerson: 0x7ff85a51d250>
2016-09-17 14:56:39.508 SharedInstance[9292:633076] <SIPerson: 0x7ff85a51d250>
2016-09-17 14:56:39.508 SharedInstance[9292:633076] <SIPerson: 0x7ff85a51d250>

拿來就可以使用的文件地址

簡單說一下如何定義swift版本的單利, 正常寫,沒研究過單利

就這樣~

摘抄

 

 

來自:http://www.jianshu.com/p/71f83c9ad257

 

 本文由用戶 vb013933 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!