单例

单例模式,也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。

#import "Person.h"

static Person *_instance;

@implementation Person

//可以在load方法中创建一个自己类的对象
+ (void)load
{
    _instance = [[Person alloc]init];
}

//在外部调用这个方法拿到单例
+ (instancetype)sharedPerson{
    return _instance;
}

//防止再创建新的对象,如果创建,抛出异常
+ (instancetype)alloc
{
    if(_instance)
    {
        NSException *exception = [NSException exceptionWithName:NSInternalInconsistencyException reason:@"只能创建一个实例,无法创建第二个" userInfo:nil];

        [exception raise];
    }
    return [super alloc];
}

@end

在考虑多线程以及ARC机制情况下的高级单例写法

#import "Person.h"

@implementation Person

static Person *_instance;

//相比重写alloc,重写allocWithZone更换,因为在执行alloc时会执行allocWithZone
//+ (instancetype)alloc
//{
//    
//}

+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
    //要考虑多线程访问安全问题

    //方法1:加互斥锁
//    @synchronized (self) {
//        if(_instance == nil)
//        {
//            _instance = [super allocWithZone:zone];
//        }
//    }

    //方法2:GCD一次性函数,本身就是线程安全的
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [super allocWithZone:zone];
    });
    return _instance;
}

//可以创建一个类方法
+ (instancetype)sharePerson
{
    return [[self alloc]init];
}

//做的更完善一点,可以重写2个copy方法,但是本类要先遵守<NSCopying,NSMutableCopying>协议
- (id)copy
{
    return _instance;
}

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

@end

非ARC(MRC)机制情况下的高级单例写法,仅了解即可

//除了以上ARC内的写法,还要重写以下函数
- (oneway void)release
{
    //置空
}

- (instancetype)retain
{
    return _instance;
}

- (NSUInteger)retainCount
{
    return MAXFLOAT;
}

单例的宏


#define SingleModeH(name) +(instancetype)share##name;

#if __has_feature(objc_arc)
//条件满足 ARC
#define SingleModeM(name) static id _instance;\
+(instancetype)allocWithZone:(struct _NSZone *)zone\
{\
static dispatch_once_t onceToken;\
dispatch_once(&onceToken, ^{\
_instance = [super allocWithZone:zone];\
});\
\
return _instance;\
}\
\
+(instancetype)share##name\
{\
return [[self alloc]init];\
}\
\
-(id)copyWithZone:(NSZone *)zone\
{\
return _instance;\
}\
\
-(id)mutableCopyWithZone:(NSZone *)zone\
{\
return _instance;\
}

#else
//MRC
#define SingleModeM(name) static id _instance;\
+(instancetype)allocWithZone:(struct _NSZone *)zone\
{\
static dispatch_once_t onceToken;\
dispatch_once(&onceToken, ^{\
_instance = [super allocWithZone:zone];\
});\
\
return _instance;\
}\
\
+(instancetype)share##name\
{\
return [[self alloc]init];\
}\
\
-(id)copyWithZone:(NSZone *)zone\
{\
return _instance;\
}\
\
-(id)mutableCopyWithZone:(NSZone *)zone\
{\
return _instance;\
}\
-(oneway void)release\
{\
}\
\
-(instancetype)retain\
{\
return _instance;\
}\
\
-(NSUInteger)retainCount\
{\
return MAXFLOAT;\
}
#endif

如果某个类想用这个宏做单例模式

h文件

#import <Foundation/Foundation.h>
#import "SingleMode.h"

@interface Person : NSObject

SingleModeH(Person);

@end

m文件

#import "Person.h"

@implementation Person

static Person *_instance;

SingleModeM(Person);

@end

这样就快速实现了单例模式

下面试试看,这样做是不是实现了单例:

Person *p1 = [[Person alloc]init];
NSLog(@"%p",p1);

Person *p2 = [[Person alloc]init];
NSLog(@"%p",p2);

Person *p3 = [Person new];
NSLog(@"%p",p3);

Person *p4 = [Person sharePerson];
NSLog(@"%p",p4);

Person *p5 = [p1 copy];
NSLog(@"%p",p5);

Person *p6 = [p1 mutableCopy];
NSLog(@"%p",p6);

results matching ""

    No results matching ""