設計模式--單例

單例是設計模式中常見的一種。

//
//  Singleton.h
//  單例
//
//  Created by hhg on 15-6-11.
//  Copyright (c) 2015年 hhg. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Singleton : NSObject

+ (instancetype)shareInstance;

@end
//
//  Singleton.m
//  單例
//
//  Created by hhg on 15-6-11.
//  Copyright (c) 2015年 hhg. All rights reserved.
//


#import "Singleton.h"

@implementation Singleton

+ (instancetype)shareInstance {
    static Singleton * singletion = nil;
    if (!singletion) {
        singletion = [[Singleton alloc]init];
    }
    return  singletion;
}

@end

調用

//
//  main.m
//  單例
//
//  Created by hhg on 15-6-11.
//  Copyright (c) 2015年 hhg. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "Singleton.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        Singleton *s1 = [Singleton shareInstance];
        Singleton *s2 = [Singleton shareInstance];
        Singleton *s3 = [Singleton shareInstance];
        NSLog(@"%p, %p, %p", s1, s2, s3);
        
    }
    return 0;
}

打印的結果:

0x102040f60, 0x102040f60, 0x102040f60

對於多線程情況,增加互斥鎖,以及copy對象優化等。

//
//  Singletion.h
//  優化後的.h文件沒有變
//
//  Created by hhg on 15-6-11.
//  Copyright (c) 2015年 hhg. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Singletion : NSObject

+ (instancetype)shareInstance;

@end
//
//  Singletion.m
//	優化後的.m文件增加互斥鎖等。
//
//  Created by hhg on 15-6-11.
//  Copyright (c) 2015年 hhg. All rights reserved.
//

#import "Singletion.h"
@interface Singletion()<NSCopying,NSMutableCopying>

@end

@implementation Singletion

static id _instance;

+ (instancetype)shareInstance {  // 提供類方法,用於外界訪問
    @synchronized (self) {
        if (!_instance) {
            _instance = [[self alloc]init];
        }
    }
    return _instance;
}

+ (instancetype) allocWithZone:(struct _NSZone *)zone { // 在這裏創建唯一的實例
    @synchronized(self) {
        if (!_instance) {
            _instance = [super allocWithZone:zone];
        }
    }
    return _instance;
}
- (instancetype)copyWithZone:(struct _NSZone*)zone { // 保證複製時不生成新對象
    return _instance;
}

- (id)mutableCopyWithZone:(nullable NSZone *)zone {
    return _instance;
}
@end

在ios中,關於多線程安全的使用,我們通常會使用dispatch_once。所以,單例的線程安全改法更貼近ios開發習慣的寫法是:

//
//  Singletion.m
//	
//
//  Created by hhg on 15-6-11.
//  Copyright (c) 2015年 hhg. All rights reserved.
//

#import "Singletion.h"
@interface Singletion()<NSCopying,NSMutableCopying>

@end

@implementation Singletion

static id _instance;

+ (instancetype)shareInstance {  // 提供類方法,用於外界訪問
    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;
}

- (instancetype)copyWithZone:(struct _NSZone*)zone { // 保證複製時不生成新對象
    return _instance;
}

- (id)mutableCopyWithZone:(nullable NSZone *)zone {
    return _instance;
}
@end

使用 NS_UNAVAILABLE 修飾單例

//
//  Singletion.h
//   
//
//  Created by hhg on 15-6-11.
//  Copyright (c) 2015年 hhg. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Singletion : NSObject

+ (nonnull instancetype)shareInstance;

- (nonnull instancetype)init NS_UNAVAILABLE;

- (nonnull instancetype)new NS_UNAVAILABLE;

@end
//
//  Singletion.m
//	 
//
//  Created by hhg on 15-6-11.
//  Copyright (c) 2015年 hhg. All rights reserved.
//

#import "Singletion.h"

@implementation Singletion

 
-(instancetype)init {
	if (self = [super init]) {
		__weak typeof(self) weakSelf = self;
		static dispatch_once_t onceToken;
		dispatch_once(&onceToken ,^{
			__strong typeof(self) strongSelf = weakSelf;
			// other coder
		});
	}
	return self;
}
 
+ (instancetype)shareInstance {  // 提供類方法,用於外界訪問
	static Singletion * _instance;
	static dispatch_once_t onceToken;
	distapch_once(&onceToken ,^{
		_instance = [[self alloc]init];
	});
	return _instance ;
}
 
@end

注:以上代碼在文檔編輯器直接盲敲的,可能會有疏漏,如複製黏貼到xcode跑起來有問題的自行修改一下,也歡迎留言修改。

相關參考:
《IQKeyboardManager》源碼

相關討論/指導:
成都_Peter

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章