手动内存管理
当我们碰到alloc,new,copy,mutableCopy时都会生成对象,会使引用计数器自动加一,相当于对对象做了一次retain,需要在适当的地方进行一次release。当我们碰到allocMyObject,newThatObject,copyThis,mutableCopyYourObject时也意味着自己生成并持有对象。
但是并不是只要以alloc/new/copy/mutableCopy开头就会生成并持有对象,就比如allocate/newer/copying/mutableCopyed就不可以
自己持有的对象一旦不使用,持有者有义务对对象进行释放,即对该对象做一次release操作,否则会造成内存泄露。
当我们在对对象进行release,当引用计数器为0时,就不可以进行访问该对象,或者再次进行release了。否则会造成野指针错误。
引入一个概念 autorelease(自动释放池):Autorelease实际上只是把对release的调用延迟了,对于每一个Autorelease,系统只是把该Object放入了当前的Autorelease pool中,当该pool被释放时,该pool中的所有Object会被调用Release。
autorelease是把需要释放的对象添加到autorelease中,并不是立即释放,到autorelease方法结束时统一对autorelease中得每一个对象进行一次release操作。
看一下alloc类方法在NSObject.m源代码中得实现
+(id)alloc
{
return [self allocWithZone:NSDefaultMallocZone()];
}
+ (id)allocWithZone:(NSZone*)z
{
return NSAllocateObject(self,0,z);
}
通过allocWithZone:类方法调用NSAllocateObject函数分配了对象,
下面我们来看看NSAllocateObject 函数。
GNUstep/modules/core/base/Source/NSObject.m NSAllocateObject ▼
struct obj_layout {
NSUInteger retained;
};
inline id
NSAllocateObject (Class aClass, NSUInteger extraBytes, NSZone *zone)
{
int size = 计算容纳对象所需内存大小;
id new = NSZoneMalloc(zone,size);
memset(new, 0, size);
new = (id)&((struct obj_layout *)new)[1];
}
NSAllocateObject 函数通过调用NSZoneMalloc 函数来分配存放对象所需的内存空间,之后将该内存空间置0,最后返回作为对象而使用的指针。
专栏区域
NSDefaultMallocZone、NSZoneMalloc等名称中包含的NSZone是什么呢?它是为防止内存碎片化而引入的结构。对内存分配的区域本身进行多重化管理,根据使用对象的目的、对象的大小分配内存,从而提高了内存管理的效率。