写一个单例

写一个单例吧,记性不好,还是烂笔头好使。
比如单例类名叫Singleton

.m 文件

#import "Singleton.h"
static Singleton* singleton = nil;
@interface Singleton()<NSCopying,NSMutableCopying>
@end
@implementation Singleton
//单例方法
+ (Singleton *)shareSingleton{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken,^{
        singleton = [[super allocWithZone:NULL] init];
    });
    return singleton;
}



/*
    重写 allocWithZone: 方法。
    如果我们创建单例的时候直接调用shareSingleton方法,已经能达到我们想要的效果,但是如果其他同事在不知情的情况下调用了 [[Singleton alloc] init]创建对象,就会重新分配一块内存,创建一个新的对象。那这样就破坏我们使Singleton以单例存在的初衷。
    alloc 方法调用时其实调用的是allocWithZone:方法,所以我们需要重写allocWithZone:方法,使它不创建新对象,而是返回单例

    注:该方法的参数 zone 可以忽略,

*/
+(instancetype)allocWithZone:(struct _NSZone *)zone{
    return [Singleton shareSingleton];
}



/*
    重写 copy 方法
    copy 方法被实例对象调用后,会被拷贝一个新的对象,存在重新分配的内存中,如此,也破坏了该类的单例模式,需要重写该方法,返回单例对象
*/
- (id)copy{
    return [Singleton shareSingleton];
}



/*
    重写mutableCopy方法
     原因同上
*/
-(id)mutableCopy{
    return [Singleton shareSingleton];
}

到这,就完成了一个单例的设计。

不知道你是否有个疑虑。[Singleton new]不也能创建一个新对象吗,为啥不重写 new 方法呢 ?因为调用 new 方法时也会调用 allocWithZone:方法。

那么[Singleton new]和[[Singleton alloc] init] 有什么区别呢?

+ new
{ 
id newObject = (*_alloc)((Class)self, 0); 
Class metaClass = self->isa; 
if (class_getVersion(metaClass) > 1) 
return [newObject init]; 
else
return newObject; 
} 

//而 alloc/init 像这样: 
+ alloc 
{ 
return (*_zoneAlloc)((Class)self, 0, malloc_default_zone()); 
} 
- init 
{ 
return self; 
} 

看源码知道,new 的内部实现就是分配内存,调用init方法,初始化对象。不同的是 alloc 使用了 zone,而 zone 这个现在可以忽略了
写一个单例_第1张图片

你可能感兴趣的:(iOS)