首页 > 系统相关 >ObjectiveC 内存管理

ObjectiveC 内存管理

时间:2024-07-11 20:29:20浏览次数:23  
标签:管理 对象 回收 Person 自动 内存 release ObjectiveC 指针

内存的五大区域

  • 栈:局部变量 (当局部变量的作用域被执行完毕之后,这个局部变量就会被系统立即回收);
  • 堆:OC对象和使用C函数申请的空间;
  • BSS段:未初始化的全局变量、静态变量,一旦初始化就回收并转存到数据段之中;
  • 数据段:已经初始化的全局变量、静态变量,直到程序结束的时候才会被回收;
  • 代码段:二进制代码,程序结束的时候,系统会自动回收存储在代码段中的数据.

        栈、BSS段、数据段、代码段存储在它们中的数据的回收,是由系统自动完成的,不需要我们干预。存储在堆中的OC对象,系统不会自动回收,直到程序结束的时候才会被回收。因此,内存管理的范围是存储在堆中的0C对象。

引用计数器

定义

  1. 每个对象都有个属性,叫做retainCount,即引用计数器,类型是unsigned long 占据8个字节.引用计数器的作用:用来记录当前这个对象有多少个人在使用它。默认情况下,创建1个对象出来这个对象的引用计数器的默认值是1。
  2. 当多1个人使用这个对象的时候。应该先让这个对象的引用计数器的值+1 ,代表这个对象多1个人使用。
  3. 这个对象少1个人使用的时候。应该先让这个对象的引用计数器的值-1 ,代表这个对象少1个人使用。
  4. 当这个对象的引用计数器变为0的时候,代表这个对象无人使用。这个时候系统就会自动回收这个对象。

如何操作引用计数器

  1. 为对象发送1条retain消息,对象的引用计数器就会加1,当多1个人使用对象的时候才发;
  2. 为对象发送1条release消息,对象的引用计数器就会减1,当少1个人使用对象的时候才发;
  3. 为对象发送1条retainCount消息,就可以取到对象的引用计数器的值;
  4. 在对象被回收的时候,会自动调用对象的dealloc方法.

        重写dealloc方法的规范:必须要调用父类的dealloc方法,并且要放在最后一句代码。

[super dealloc];

内存管理的分类

  • MRC: Manual Reference Counting 手动引用计数
  • -------------------i0S5-------------------------
  • ARC: Automatic Reference Counting 自动引用计数

内存管理的原则

  • 有对象的创建,就要匹配1个release;

  • retain的次数和release的次数要匹配;
  • 谁用谁retain,谁不用谁release 。

回收对象的本质

        申请1个变量,实际上就是向系统申请指定字节数的空间,这些空间系统就不会再分配给别人了, 当变量被回收的时候,代表变量占用的字节空间从此以后系统可以分配给别人使用了,但是字节空间中存储的数据还在。

成员变量的setter方法

- (void)setCar:(Car *)car
{
    if(_car!=car)// 旧对象不是同一个对象
    {
        [_car release];// release旧对象
         _car = [car release];// retain新对象
     }
}

@property

@property的作用

  1. 简化代码@property 自动生成实例变量的声明,以及对应的 Getter 和 Setter 方法,避免繁琐的手动编写。

  2. 定义属性的访问控制:通过各种修饰符,可以控制属性的访问方式(如读写权限、内存管理语义等)

@property的参数

  • nonatomic atomic:默认是atomic,是线程安全的,但效率低,建议atomic;
  • retain assign:默认值是assign,生成的setter方法的视线就是直接赋值;retain的setter方法实现就是标准的MRC内存管理代码;当属性的类型是OC对象时,就使用retain,非OC对象使用assign;但是reatin并不会在dealloc中生成release的代码,我们需要手动写;
  • readwrite readonly:前者同时生成getter、setter,后者只会生成setter;

@class

        当两个类相互包含的时候,如Person.h中包含Book.h 而Book.h中又包含Person.h。这个时候,就会循环引用,就会造成无限递归的问题,而导致无法编译通过。

        解决方法:其中一边不要使用#import引入对方的头文件,而是使用@class+类名来标注这是1个类。这样子就可以在不引入对方头文件的情况下,告诉编译器这是1个类。

@cLass与#import的区别

  1. #import是将指定的文件的内容拷贝到写指令的地方。
  2. @class 并不会拷贝任何内容。只是告诉编译器,这是1个类,这样编译器在编译的时候才可以知道这是1个类。

对象相互引用

        A对象的属性是B对象,B对象的属性是A对象。这个时候如果两边都使用retain 那么就会发生内存泄露。解决方案:1端使用retain 另外1端使用assign,使用assign的那1端在dealloc中不再需要release了。

自动释放池

原理

        存入到自动释放池中的对象,在自动释放池被销毁的时候。会自动调用存储在该自动释放池中的所有对象的release方法。

        可以解决的问题:将创建的对象,存入到自动释放池之中,就不再需要手动的relase这个对象了。

创建自动释放池

@autoreleasepool
{

}

将对象存储到自动释放池

  1. 在自动释放池之中调用对象的autorelease方法,就会将这个对象存入到当前自动释放池之中;
  2. 这个autorealse方法返回的是对象本身,所以我们可以这么写:
@autoreleasepool
{
    Preson *p=[[[Person alloc] init]autorelease];
}

        此时当自动释放池执行完毕之后就会立即为自动释放池里的对象发送一条release方法。(只是省略创建对象匹配的release) 。

类方法规范

  1. 一般情况下,要求提供与自定义构造方法相同功能的类方法.这样可以快速的创建1个对象;
  2. 使用类方法创建的对象,要求这个对象在方法中就已经被autorelease过了。这样,我们只要在自动释放池中,调用类方法来创建对象,那么创建的对象就会被自动的加入到自动释放中。
  3. 如果没有参数就直接是类名 如果有参数就是 类名withXX:
+ (instancetype) person
{
return [[[self alloc] init autoreleasel;
}

        这样,我们直接调用类方法就可以得到1个已经被autorelease过的对象。       

@autoreleasepool
{
Person *p1 = [Person person];
//这个p1对象已经被autorelase过了.不需要再调用autorelase
1/这个p1对象就被存储到当前自动释放池之中,
}//当自动释放池结束.就会为存储在其中的p1对象发送release消息

 ARC

        当ARC开启时,编译器会自动的在合适的地方插入retain、release、autorelase代码。编译器自动为对象做引用计数,而作为开发者,完全不需要担心编译器会做错(除非开发者自己错用了ARC)。另外,在dealloc中,不允许[super dealloc]。

ARC机制下,对象何时被释放?

  • 本质:对象的引用计数器为0的时候,自动释放;
  • 表象:只要没有强指针指向这个对象,这个对象就会立即回收;

强指针与弱指针

强指针:默认情况下,我们声明1个指针就是1个强指针。也可以使用_strong来显示的声明这是1个强指针.

  • Person *p1;这是1个强指针,指针默认情况下都是1个强指针。
  • _strong Person *p2;这也是1个强指针.使用_strong来显示的声明强指针。

弱指针:使用_weak标识的指针就叫做弱指针.

无论是强指针还是弱指针,都是指针,都可以用来存储地址,这1点没有任何区别。都可以通过这个指针访问对象的成员。唯一的区别就是在ARC模式下,他们用来作为回收对象的基准。

但是不能创建一个用弱指针存储某个对象,因为该对象刚刚创建出来就会被释放。

单个对象的内存管理

在ARC的机制下:当1个对象没有任何的强指针指向它的时候,这个对象就会被立即回收。

1)当指向对象的所有的强指针被回收的时候,对象就会被立即回收。

int main(int argc, const char * argv[])

{

@autoreleasepool

{Person *p1 = [Person new];//p1是1个强指针.

Person *p2 = P1;//p2也是个强指针.P1和p2都指向Person对象.

//每1个指针变量默认情况下都是1个强指针变量;

}//当执行到这里的时候。P1指针被回收,p2指针也被回收。那么Person对象就没有任何//强指针指向它了,对象就在这被回收.

return 0;

}

2)将所有指向对象的强指针赋值为nil的时候,对象就会被立即回收.

int main(int argc, const char * argvll)

@autoreleasepool

{Person *p1 = [Person new] ;//p1是1个强指针,

//因为我们说过,每1个指针变量默认情况下都是1个强指针变量。

P1 = nil;//当执行到这句话的时候.p1赋值为nil.

//p1指针不再执行Person对象.

//Person对象没有被任何的指针所指向,所以Person对象在这里被释放.

}

return 0;

}

使用建议

1)在ARC机制下.如果属性的类型是OC对象类型的.绝大多数场景下使用strong;

2)在ARC机制下.如果属性的类型不是OC对象类型的,使用assign;

3)strong和weak都是应用在属性的类型是OC对象的时候.属性的类型不是OC对象的时候就使用assign。

强指针相互引用--将一个改为weak

程序使用ARC,但有的类是MRC.使用-fno-objc-arc编译这些类

标签:管理,对象,回收,Person,自动,内存,release,ObjectiveC,指针
From: https://blog.csdn.net/m0_59680769/article/details/140358632

相关文章

  • Java计算机毕业设计基于Web的社区留守儿童管理系统(开题+源码+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着社会经济的快速发展,城乡差距日益显著,大量农村劳动力向城市转移,导致农村地区出现大量留守儿童。这些孩子因父母长期不在身边,面临着生活、学习、心......
  • Java计算机毕业设计基于的商品分析与管理系统的设计和实现(开题报告+源码+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景在数字化时代,商品市场的竞争日益激烈,企业为了保持竞争优势,需要更加精准地把握市场动态,优化商品结构,提升运营效率。传统的商品管理方式往往依赖于人工......
  • 7.11 linux用户与权限管理,linux安装mysql
    一、关于用户名    1、密码占位,真正的密码是在/etctshadow中,shadow文件只有root才可以看到        2、用户id,0为超级用户,1-499是系统用户伪用户,500-65535为普通用户    3、初始组用户添加用户默认添加同名组/etc/group    4、用户说明,......
  • 微信小程序源码-基于Java后端的汽车维修项目管理系统毕业设计(附源码+论文)
    大家好!我是程序员一帆,感谢您阅读本文,欢迎一键三连哦。......
  • Java实现学生管理系统
        学生类packageStudentsSystem;publicclassStudent{privateStringid;privateStringname;privateintage;privateStringaddress;publicStudent(){}publicStudent(Stringid,Stringname,intage,Stringaddress......
  • 【内测招募】Mac窗口管理神器
    最近我们研发了一款Mac窗口管理应用,它能快速启动多个应用并还原窗口位置和大小,很好地提高电脑使用效率。目前正在招募内测用户阶段,你的建议能让我们更好地优化这款应用。(见P1)......
  • 基于QT开发的反射内存小工具
    前言最近项目需要需要开发一个反射内存小工具,经过2天的修修改终于完成了。界面如下:功能简介反射内存指定地址数据读取反射内存指定地址数据写入反射内存指定地址数据清理十进制、十六进制、二进制数据相互转换部分代码voidRfmMain::setWOtherEditData(constQStri......
  • 【深度好文】合作伙伴关系管理自动化:双向共赢新趋势
    在当今快速变化的商业环境中,合作伙伴关系已成为企业成功的关键因素之一。为了更高效地管理这些关系,合作伙伴关系管理自动化正逐渐成为行业的新趋势,它不仅简化了管理流程,更促进了双方共赢的局面。一、传统管理 VS 自动化管理提高效率,增加合作深度传统上,合作伙伴关系的管......
  • 实战Qt开发WordBN笔记软件#02 通过Gitee创建YourWordBN仓库;学会GIT常用指令,并实现多分
    01背景【WordBN字远笔记】是天恩软件工作室开发的一款免费笔记软件;WordBN基于VS2019、Qt6.5开发,使用QtQuick(QML)开发语言。本课程将以【WordBN字远笔记】的界面为实战基础,详细介绍如何基于Qt/QML开发语言,从零开始开发一套真正的程序,包括国际化、版本发布、安装包制作等项目......
  • 2024年10款免费的项目管理软件推荐
    本文向大家推荐10款2024年免费使用的项目管理软件,其中包括桌面应用和基于Web平台的多种产品,同时还涵盖了一些优秀的开源软件。1.禅道开源项目管理软件禅道是一款开源的、基于Web的项目管理软件,其功能丰富且操作简便,为团队提供了一套完整的项目管理解决方案。该软件不仅具......