大家平时写单例的时候可能没注意到,如果别人init了这个类,就会创建一个新的对象,要保证永远都只为单例对象分配一次内存空间,写法如下:
#import "Singleton.h"
@implementation Singleton
static Singleton* _instance = nil;
+(instancetype) shareInstance
{
static dispatch_once_t onceToken ;
dispatch_once(&onceToken, ^{
_instance = [[super allocWithZone:NULL] init] ;
}) ;
return _instance ;
}
+(id) allocWithZone:(struct _NSZone *)zone
{
return [Singleton shareInstance] ;
}
-(id) copyWithZone:(struct _NSZone *)zone
{
return [Singleton shareInstance] ;
}
@end
测试一下:
Singleton* obj1 = [Singleton shareInstance] ;
NSLog(@"obj1 = %@.", obj1) ;
Singleton* obj2 = [Singleton shareInstance] ;
NSLog(@"obj2 = %@.", obj2) ;
Singleton* obj3 = [[Singleton alloc] init] ;
NSLog(@"obj3 = %@.", obj3) ;
Singleton* obj4 = [[Singleton alloc] init] ;
NSLog(@"obj4 = %@.", [obj4 copy]) ;
可以发现打印的结果都是一样的:
2014-12-15 16:11:24.734 ObjcSingleton[8979:303] obj1 = <singleton: 0x100108720="">
2014-12-15 16:11:24.735 ObjcSingleton[8979:303] obj2 = <singleton: 0x100108720="">
2014-12-15 16:11:24.736 ObjcSingleton[8979:303] obj3 = <singleton: 0x100108720="">
2014-12-15 16:11:24.736 ObjcSingleton[8979:303] obj4 = <singleton: 0x100108720="">
看了几天关于NSZone的文章,自己总结了下 NSZone。
废话不多说。
在网上看到这么一句话:NSZone可以想象成一个内存池,alloc或dealloc都是在内存池进行的。
官方文档说:NSZone是apple用来说分配和释放内存的一种方式,它不是一个对象,而是使用c结构存储了关于对象的内存信息。
cocoa会系统默认的NSZone来对对象进行管理,然而大量对象的释放可能导致内存严重碎片化,cocoa本身有过优化,每次alloc的时候会试图去填满内存空隙,但是时间开销会很大,这时候我们可以创建一个自己的NSZone,将alloc和cope全部指定到自定义的NSZone中,可以减少时间开销。自定义的NSZone可以一次性释放掉zone里你创建的全部东西,节省了大量的dealloc时间。
平时我们初始化对象的时候比如[[Class alloc]init],有两个方法alloc和init ,alloc 方法是给对象分配内存空间,init则是初始化。而allocWithZone也是给对象初始化的方法,一般用法是[[Class allocWithZone:NULL]init]。在苹果的官方文档中写过allocWithZone方法是历史遗留问题,现在也不使用了,现在当我们alloc的时候会覆盖掉allocWithZone。
copeWithZone同理。