Objective-C中Alloc和AllocWithZone

1、先看看单例的实现代码

#import "Singleton.h"

@implementation Singleton
static Singleton* _instance = nil;
+(instancetype) shareInstance
{
    static dispatch_once_t onceToken ;
    dispatch_once(&onceToken, ^{
    _instance = [[super allocWithZone:NULL] init] ;
    //为什么不用下面这句呢?
    //为什么要覆盖allocWithZone方法,到底alloc 和 allocWithZone有什么区别呢?
    //_instance = [[super alloc] init] ;
}) ;
return _instance ;
}

+(id) allocWithZone:(struct _NSZone *)zone
{
    return [Singleton shareInstance] ;
}

-(id) copyWithZone:(struct _NSZone *)zone
{
    return [Singleton shareInstance] ;
}
@end

2、alloc 和 allocWithZone有什么区别

初始化一个对象的时候,[[Class alloc] init],其实是做了两件事。
alloc 给对象分配内存空间,init是对对象的初始化,包括设置成员变量初值这些工作。
而给对象分配空间,除了alloc方法之外,还有另一个方法: allocWithZone.
使用alloc方法初始化一个类的实例的时候,默认是调用了allocWithZone的方法。为了保持单例类实例的唯一性,需要覆盖所有会生成新的实例的方法,如果初始化这个单例类的时候不走[[Class alloc] init] ,而是直接 allocWithZone, 那么这个单例就不再是单例了,所以必须把这个方法也堵上。

3、什么是NSZone?

NSZone不是一个对象,而是使用C结构存储了关于对象的内存管理的信息。cocoa Application使用一个系统默认的NSZone来对应用的对象进行管理。
那么在什么时候你会想要有一个自己控制的NSZone呢?当默认的NSZone里面管理了大量的对象的时候。这种时候,大量对象的释放可能会导致内存严重碎片化,cocoa本身有做过优化,每次alloc的时候会试图去填满内存的空隙,但是这样做的话时间的开销很大。于是乎,你可以自己创建一个NSZone,这样当你有大量的alloc请求的时候就全部转移到指定的NSZone里面去,减少了大量的时间开销。而且,使用NSZone还可以一口气把你创建的zone里面的东西都清除掉,省掉了大量的时间去一个个dealloc对象。
总的来说,当你需要创建大量的对象的时候,使用NSZone还是能节省一些时间的。多个对象在同一时间alloc可以减少分页使用,而且在同一个时间dealloc可以减少内存碎片。
allocWithZone不被Apple鼓励使用,基本上多数时候程序员也不需要自己去管理自己的zone。

    原文作者:GabrielPanda
    原文地址: https://www.jianshu.com/p/0772490e2c03
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞