iOS开发之内存管理

iOS开发之内存管理

整理一下iOS内存管理的 相关知识,供自己也供新学习iOS的同学们参考。 
因为objective-c是c语言的超集,我们先来复习一下c语言的内存管理,在ANSI标准定义的函数库<stdlib.h>里有如下几个与内存操作有关的函数: 
void *calloc(size_t nobj, size_t size) :calloc函数为由nobj个长度为size的对象组成的数组分配内存,并返回指向分配内存区域的指针;若无法满足要求,则返回NULL。该空间的初始长度为0字节。
 
void *malloc(size_t size):malloc函数为长度为size的对象分配内存,并返回指向分配区域的指针;若无法满足要求,则返回NULL。该函数不对分配的内存区域进行初始化。
 
void *realloc(void *p, size_t size):realloc函数将p指向的对象的长度修改为size个字节。如果新分配的内存比原内存大,则原内存的内容保持不变,增加的空间不进行初始化。如果新分配的内存比原内存小,则新分配内存单元不被初始化。realloc函数返回指向新分配空间的指针;若无法满足要求,则返回NULL,在这种情况下,原指针指向的单元内容保持不变。
 
void free(void *p):free函数释放p指向的内存空间。当p的值为NULL时,该函数不执行任何操作。p必须指向先前使用动态分配函数malloc、realloc或calloc分配的空间。
 在objective-c中,与内存管理有关的几个关键动作如下:
  • 生成对象
  • 持有对象
  • 释放对象
  • 废弃对象
这几个动作均可以落实到NSObject类上。下面分别研究。
 
一、生成对象
NSObject类提供了alloc方法,很可惜我们看不到源代码。不过有一个名为GNUStep 的开源项目,它是Cocoa框架的互换框架,从使用者的角度来讲,两者的行为和实现方式非常相似。我们可以通过研究GNUStep的源码来理解Cocoa的实现。 我从这一地址下载了源码: ftp://ftp.gnustep.org/pub/gnustep/core/gnustep-base-1.24.0.tar.gz  。 
打开Source文件夹下的“NSObject.m”文件,可以看到类方法 alloc的实现:

+ (id) alloc

{

  return [self allocWithZone: NSDefaultMallocZone()];

}

可以看到,它只是简单的调用了自己的allocWithZone:方法,关于Zone是什么,我们暂时不去理会。再来追踪allocWithZone:方法:

+ (id) allocWithZone: (NSZone*)z

{

  return NSAllocateObject (self0, z);

}

又是直接调用 NSAllocateObject方法,再来追踪:

inline id

NSAllocateObject (Class aClass, NSUInteger extraBytes, NSZone *zone)

{

  id new;

  int size;

 

  size = class_getInstanceSize(aClass) + extraBytes + sizeof(struct obj_layout);

  if (zone == 0)

    {

      zone = NSDefaultMallocZone();

    }

  new = NSZoneMalloc(zone, size);

  if (new != nil)

    {

      memset (new, 0, size);

      new = (id)&((obj)new)[1];

      object_setClass(new, aClass);

      AADD(aClass, new);

    } 

  return new;

}

为便于阅读,以上代码做了简化。我们可以看到,在计算新分配的内存大小 size 的时候,使用了如下语句:

size = class_getInstanceSize(aClass) + extraBytes + sizeof(struct obj_layout);

 顾名思义, class_getInstanceSize应该计算该类型所需空间大小,它的代码实现我们先不去管它。而extraBytes呢?在allocWithZone函数的实现代码里我们可以看到,它被赋予了0值。那么obj_layout是什么东东呢?来看源代码:

struct obj_layout {

    char padding[ALIGN - ((UNP % ALIGN) ? (UNP % ALIGN) : ALIGN)];

    NSUInteger retained;

};

typedef struct obj_layout *obj;

这个结构体里面有一个整数  retained,用来保存引用计数。
关于zone,我们可以认为是内存里的一块区域。在获得了size和zone之后,NSAllocateObject进行了实际的内存分配:
new = NSZoneMalloc(zone, size);
  NSZoneMalloc函数,看其名字,似乎跟C标准库里的函数malloc大有渊源。它分配的内存,应该跟上文所列的malloc函数一样,没有进行初始化。所以,才会有接下来这一句:
memset (new, 0, size);
 对这块内存初始化为0. 在这块内存的顶端,有一块  sizeof ( struct  obj_layout)大小的区域,存放了obj_layout这一结构体。new指针指向内存顶端。如下图所示:
内存分配结构 001
接下来的这一句,就很关键了:
new = ( id )&((obj)new)[ 1 ]
这一操作把new指针从新分配的内存顶端下移到了aClass实例所在的内存区域。如下图所示:
内存分配结构 002
接下来的这一句:
object_setClass(new, aClass);
对new所在的内存区域进行了设置,设置class类型为aClass(在这里是NSObject)。我们暂时不去深究。再往下的这一句就很关键了:
AADD(aClass, new);
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
城市应急指挥系统是智慧城市建设的重要组成部分,旨在提高城市对突发事件的预防和处置能力。系统背景源于自然灾害和事故灾难频发,如汶川地震和日本大地震等,这些事件造成了巨大的人员伤亡和财产损失。随着城市化进程的加快,应急信息化建设面临信息资源分散、管理标准不统一等问题,需要通过统筹管理和技术创新来解决。 系统的设计思路是通过先进的技术手段,如物联网、射频识别、卫星定位等,构建一个具有强大信息感知和通信能力的网络和平台。这将促进不同部门和层次之间的信息共享、交流和整合,提高城市资源的利用效率,满足城市对各种信息的获取和使用需求。在“十二五”期间,应急信息化工作将依托这些技术,实现动态监控、风险管理、预警以及统一指挥调度。 应急指挥系统的建设目标是实现快速有效的应对各种突发事件,保障人民生命财产安全,减少社会危害和经济损失。系统将包括预测预警、模拟演练、辅助决策、态势分析等功能,以及应急值守、预案管理、GIS应用等基本应用。此外,还包括支撑平台的建设,如接警中心、视频会议、统一通信等基础设施。 系统的实施将涉及到应急网络建设、应急指挥、视频监控、卫星通信等多个方面。通过高度集成的系统,建立统一的信息接收和处理平台,实现多渠道接入和融合指挥调度。此外,还包括应急指挥中心基础平台建设、固定和移动应急指挥通信系统建设,以及应急队伍建设,确保能够迅速响应并有效处置各类突发事件。 项目的意义在于,它不仅是提升灾害监测预报水平和预警能力的重要科技支撑,也是实现预防和减轻重大灾害和事故损失的关键。通过实施城市应急指挥系统,可以加强社会管理和公共服务,构建和谐社会,为打造平安城市提供坚实的基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值