iOS开发之内存管理

2023-11-18

iOS开发之内存管理

  • 一、垃圾回收机制
  • 二、内存管理的概念
  • 三、OC内存管理注意事项
  • 四、MRC相关语法

一、垃圾回收机制
与Java语言相同Objective-c 2.0之后,也提供了垃圾回收机制。OC是支持垃圾回收机制的(Garbage collection简称GC),macOS开发中是支持的。但是在iOS移动终端设备中,并不支持垃圾回收机制。因此,iPhone并不能对内存进行自动垃圾回收处理(autorelease),并且他与GC的机制是不一样的。
ARC是在IOS5之后推出的新技术,在Xcode4.2及之后的版本中由于引入了ARC(Automatic Reference Counting)机制,程序编译时Xcode可以自动给你的代码添加内存释放代码,如果编写手动释放代码Xcode会报错。因此需要注意垃圾回收机制并不是ARC,ARC也是需要管理内存的,只不过是隐式的管理内存,编译器会在适当的地方自动插入retain,release和autorelease.
知识拓展:在Java中,程序员不需要去关心内存动态分配和垃圾回收的问题,这一切都交给了JVM来处理。Java中标记垃圾的算法主要有两种, 引用计数法和可达性分析算法。

二、内存管理中的几个概念:
引用计算器:既retainCount,每个OC对象内部都有1个8字节空间用来存储retainCount,表示有多少”人”正在使用;
对象刚被创建时,默认计数值就为1,当计数值为0时,系统会自动调用dealloc方法将对象销毁
引用计数器的用法:给对象发送相应的技术操作来改变计数器的值
retain消息:使计数器+1
release消息:使计数器-1
retainCount消息:得到当前当前retainCount的值

三、OC内存管理开发中需要事项
其一野指针,其二内存泄漏。
1)野指针:即指针所指的对象已经被销毁,但后续还在使用该指针,此时指针指向了一个什么都不是的东西,我们称它为野指针,那么如何防止野指针的,一般处理的方式是对象进行release操作后,在赋值对象nil值。
2)内存泄漏:在操作对象是没有遵循内存配对原则,创建了对象了,却未对对象进行销毁,此时这个未被销毁的对象就是我们所谓的内存中泄漏的对象,这种行为也就是所谓的内存泄漏,内存泄漏不会影响对象的正常运行,但会影响程序的效率。
除此之外还有1)提前释放:如果没有使用空间直接free 。2)重复释放,如果你对一个空间进行了多次free 。

四、MRC(Manual Reference Counting)相关语法
1.关闭ARC
target -》 build setting - 》搜索 gar YES to NO

这里写图片描述

2.ARC和MRC混编
[工程]—>[Build Phases]—>[Compile Sources]—>
双击不想参与ARC的文件-fno-objc-arc
这里写图片描述

3.MRC管理黄金法则
1.凡是使用alloc,retain ,new ,copy(开头),mutableCopy(开头)的方法,都必须使用release 或者 autorelease 方法来【释放】
2.谁写alloc 谁负责release 那个类alloc 那个类release

4.一个简单的例子说明MRC
这里有一个Person类
这里写图片描述
这里是打印结果
这里写图片描述
我们在看看下面这一个例子
这里写图片描述
当执行release操作时,一个对象的引用计数为0时,它就会被释放掉。

AutoReleasePool

什么是autorelease?
autorelease类似于C语言中Automatic variable自动变量,程序执行时,若某自动变量超出其作用域,该自动变量将被自动废弃。
autorelease何时释放?
在没有使用@autoreleasepool的情况,autorelease对象是在当前的runloop迭代结束时释放。每个runloop中都会创建一个autoreleasepool并在runloop迭代结束进行释放。如果是手动创建autoreleasepool,自己创建Pool并释放。

// MRC

NSAutoreleasePool *pool = [NSAutoreleasePool alloc] init];

id obj = [NSObject alloc] init];

[obj autorelease];

[pool drain];

// ARC

@autoreleasepool {

id obj = [NSObject alloc] init];

}

可以发现:整个 iOS 的应用都是包含在一个自动释放池 block 中的

int main(int argc, char * argv[]) {
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

@autoreleasepool{} 本质上是一个结构体:

struct __AtAutoreleasePool {
__AtAutoreleasePool() {atautoreleasepoolobj = objc_autoreleasePoolPush();}
~__AtAutoreleasePool() {objc_autoreleasePoolPop(atautoreleasepoolobj);}
void * atautoreleasepoolobj;
};
这个结构体在初始化的时候会调用:objc_autoreleasePoolPush() 方法
在析构的时候,会调用:objc_autoreleasePoolPop 方法
这表明,main函数实际工作的时候,是这样的:

int main(int argc, const char * argv[]) {
    {
        void * atautoreleasepoolobj = objc_autoreleasePoolPush();
        
        // do things you want
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
        
        objc_autoreleasePoolPop(atautoreleasepoolobj);
    }
    return 0;
}

那么 objc_autoreleasePoolPushobjc_autoreleasePoolPop又是什么呢?

void *objc_autoreleasePoolPush(void) {
return AutoreleasePoolPage::push();
}
void objc_autoreleasePoolPop(void *ctxt) {
AutoreleasePoolPage::pop(ctxt);
}

上面的方法看上去是对 AutoreleasePoolPage 对应静态方法 push 和 pop 的封装

class AutoreleasePoolPage {
magic_t const magic; //AutoreleasePoolPage 完整性校验
id *next;
pthread_t const thread; //所在线程
AutoreleasePoolPage * const parent;
AutoreleasePoolPage *child;
uint32_t const depth;
uint32_t hiwat;
};

每一个自动释放池都是由一系列的 AutoreleasePoolPage 组成的,并且每一个 AutoreleasePoolPage 的大小都是 4096 字节(16 进制 0x1000)
自动释放池就是由 AutoreleasePoolPage 构成的双向链表。

POOL_SENTINEL(哨兵对象)
在每个自动释放池初始化调用 objc_autoreleasePoolPush 的时候,都会把一个 POOL_SENTINEL push 到自动释放池的栈顶,并且返回这个 POOL_SENTINEL 哨兵对象。

int main(int argc, const char * argv[]) {
    {
    	//这里的 atautoreleasepoolobj 就是一个 POOL_SENTINEL
        void * atautoreleasepoolobj = objc_autoreleasePoolPush();
        
        // do whatever you want
        
        objc_autoreleasePoolPop(atautoreleasepoolobj);
    }
    return 0;
}

上面的 atautoreleasepoolobj 就是一个 POOL_SENTINEL。
而当方法 objc_autoreleasePoolPop 调用时,就会向自动释放池中的对象发送 release 消息,直到第一个 POOL_SENTINEL。

注:下篇文章博主会详细讲解各种属性修饰符,请持续关注;

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

iOS开发之内存管理 的相关文章

  • iOS:如何在不降低 fps 的情况下播放音频?

    我正在使用 Sprite Kit 最好使用 Swift 库 为 iOS 9 开发游戏 目前 我正在使用 Singleton 在其中预加载音频文件 每个文件都连接到一个单独的 AVAudioPlayer 实例 这是一个简短的代码片段来了解这个
  • 如何以编程方式设置设备(UI)方向?

    希望屏幕 UI 上的所有内容都能够从横向左向右旋转 反之亦然 我该怎么做呢 这是私人的吗 我知道 BOOL shouldAutorotateToInterfaceOrientation UIInterfaceOrientation inte
  • NSCalendar 返回明年第一周上周一的错误日期

    我使用下面的代码使用随机日期来计算上周一 哪个工作文件但我的代码在明年日期中断 下面是相同的代码 NSDate date NSDate dateWithTimeIntervalSince1970 1483620311 228 NSLog c
  • 如何检测 UISwipeGestureRecognizer 的结束?

    来自苹果文档 滑动是一种离散手势 因此每个手势仅发送一次关联的操作消息 void touchesEnded NSSet touches withEvent UIEvent event 当我使用 UISwipeGestureRecognize
  • 使用远程图像创建 MSSticker

    我正在尝试找出使用网络上托管的图像创建 MSStickers 的方法 我可以使用本地图像创建 MSStickers 例如 NSString imagePath NSBundle mainBundle pathForResource imag
  • mgwt - 以编程方式改变方向

    是否可以在 gwt mgwt 应用程序中更改强制执行特定的屏幕方向 可以说我希望用户始终以横向模式使用应用程序 这取决于 是作为phonegap应用程序 而不是在浏览器内部 如果您作为 Web 应用程序运行 则不需要t get any co
  • UIStackView分布均匀填充

    所以 我有一个UIStackView其中包含四 4 UIViews 如果我删除其中一 1 个UIViews 其他三 3 个将填满UIStackView 我的问题 如何添加最大高度UIView这样它就不会填满整个空间UIStackView即使
  • AFNetworking XML 请求问题

    我在用着AFNetworking 2使用 JSON 响应 它工作正常 现在我必须将其转换为 XML 而不是使用 JSON 因为服务器响应是 XML 格式的 在我搜索之后 我找到了这段代码 但它不起作用 与 Charles 我发现请求是错误的
  • Cordova 2.4.0 或 2.5.0 或 2.6.0 和 requirejs

    Cordova 2 4 0 及更高版本支持 AMD 加载到 javascript 中 我特别希望将 Cordova 2 5 0 与最新版本的 RequireJS backbone jquery jquery mobile 一起使用 我还没有
  • iOS - 如何在 swift 中使用 `NSMutableString`

    我已经看过这段 Objective C 代码 但我很难在 swift 中做同样的事情 NSMutableAttributedString res self richTextEditor attributedText mutableCopy
  • 如何找到键盘未覆盖的视图部分(UIModalPresenationStyleFormSheet)?

    我有一个视图控制器 显示带有 UITextView 的视图 并且我想在键盘出现时调整视图的大小 以便 UITextView 不会被键盘覆盖 我几乎在所有情况下都可以正常工作 据我所知 仅当视图控制器以 ModalPresentationSt
  • iOS、通用链接、Swift。 continueUserActivity 未调用

    我正在为我们的 iOS 应用程序实现通用链接 这是我的一小部分 AppDelegate private func application application UIApplication openURL url URL sourceApp
  • 将自定义数据包含到 iOS 故障转储中

    你好 堆栈溢出 有一个简单的问题要问您 当我的应用程序在用户的设备上崩溃时 是否可以将自定义错误数据嵌入到自动生成的 iOS 故障转储中 例如 我的 SQlite 数据库由于某种原因无法运行 例如 数据库文件已损坏 我无法从这个错误中恢复
  • 从一个模态视图无缝翻转到另一个模态视图,而不显示纯色背景

    我的 iPad 应用程序的 UI 如下 当我点击Settings按钮 我希望对话框水平翻转以显示设置对话框 我这个工作正常 但是 当对话翻转时会显示背景颜色 如你看到的 有什么办法可以让对话框翻转时不显示该颜色块吗 我希望它看起来更加无缝
  • 如何向标准 UIButton 添加徽章? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 是否可以在标准中添加看起来标准的徽章UIButton 如果不支持半原生 那么实现此目的最简单的方法是什么 示例图片 这是 Sascha
  • 在实例化对象之前是否可以检查故事板中是否存在标识符?

    在我的代码中我有这一行 但我想知道是否有办法检查是否 一些控制器 在我将它与 一起使用之前就存在实例化ViewControllerWithIdentifier 方法 如果标识符不存在 则应用程序崩溃 如果没有好的方法 这并不是一个大问题 我
  • UIView 圆角 - Swift 2.0?

    我会尝试将一些项目更新到 Swift 2 0 我有一个视图 左上角有一个圆角 在 Swift 没有警告 没有错误 只是没有圆角 这就是它在 Swift let maskPath UIBezierPath roundedRect conten
  • CoreBluetooth:检测设备超出范围/连接超时

    我正在设计一个 iOS 框架来处理多个 BLE 设备 均为同一类型 目前一切都运行良好 除了一件事 客户想要一个包含可用设备的列表 但是 我如何检测过去发现的设备何时不再可用 当我尝试连接到不再可用的设备时 会出现另一个问题 文档说 连接尝
  • 是否可以跨 2 个不同的 iOS 应用程序访问数据?

    假设我在 App1 中存储了一些 ID 数据 并希望在同一设备上的 App2 中访问它 平台上可以这样吗 如果没有的话有什么解决方法吗 您可以使用iOS 钥匙扣 http developer apple com library ios do
  • 更改 iOS7 中 UIAlertView 的字体大小

    我想更改alertView中消息文本和标题文本的字体大小 苹果网站上没有任何文档谈到这一点 但苹果在其子类注释中表示 UIAlertView 类旨在按原样使用 请参考以下链接 https developer apple com librar

随机推荐

  • 利用Figlet工具创建酷炫Linux Centos8服务器-登录欢迎界面-SHELL自动化编译安装代码

    因为我们需要生成需要的特定字符 所以需要在当前服务器中安装Figlet 默认没有安装包的 其实如果我们也只要在一台环境中安装 然后需要什么字符只要复制到需要的服务器中 并不需要所有都安装 同样的 我们也可以利用此生成的字符用到脚本运行的开始
  • 大数据入门 - 基础概念

    文章目录 1 发展历史 2 分布式系统 可靠性 可扩展性 可维护性 4 单机引擎的问题 事务 写入和存储 数据的序列化 3 GFS Google File System master 的快速恢复性和可用性保障 数据写入的优化 4 MapRe
  • QT中setWindowFlags和 setAttribute使用详解及注意问题

    1 setWindowFlags QT WindowFlags 主要设置一些窗口标志 平常开发中主要有两类需求 1 1 将某一子窗口设置为最顶层窗口 使用Qt Tool 属性 setWindowFlags Qt Tool 1 2 重新定义窗
  • 【Redis】4、全局唯一 ID生成、单机(非分布式)情况下的秒杀和一人一单

    目录 一 利用 Redis 实现全局唯一 ID 生成 1 为啥要用全局唯一 ID 生成 2 全局唯一 ID 生成器 3 全局 ID 的结构 4 代码实现 RedisIdWorker Test 5 全局唯一 ID 其他生成策略 二 添加优惠券
  • 使用python爬取淘宝商品信息

    要使用Python爬取淘宝商品信息 您可以按照以下步骤 安装必要的库 您需要安装Python的requests库和BeautifulSoup库 要使用Python爬取淘宝商品信息 您可以按照以下步骤 安装必要的库 您需要安装Python的r
  • 「科普」一文读懂生产制造MES系统

    谈及MES必须先谈生产 那什么是生成呢 生产管理是通过对生产系统的战略计划 组织 指挥 实施 协调 控制等活动 实现系统的物质变换 产品生产 价值提升的过程 生产管理是企业价值链的主要环节 是构成企业核心竞争力的关键内容 1 什么是MES系
  • ViT(vision transformer)原理快速入门

    本专题需要具备的基础 了解深度学习分类网络原理 了解2017年的transformer Transformer 技术里程碑 ViT简介 时间 2020年CVPR 论文全称 An Image is Worth 16 16 Words Tran
  • Atlassian Confluence 远程代码执行漏洞(CVE-2022-26134)复现

    Confluence介绍 Confluence是一个专业的企业知识管理与协同软件 也可以用于构建企业wiki 使用简单 但它强大的编辑和站点管理特征能够帮助团队成员之间共享信息 文档协作 集体讨论 信息推送 漏洞概述 Atlassian C
  • mysql 子查询(六)之主查询和子查询的执行顺序

    那么 什么是相关子查询呢 举个例子 查询员工表中薪水大于本部门平均薪水的员工 首先构建思路 说到底还是查询员工 所以主查询是查询员工 然后在where后面增加子查询 查询薪水大于本部门平均薪水 开始写sql 如下 问题来了 查询某个部门的薪
  • shiro-session-ehcache配置

    首先准备好jar包 shiro的主要四个 ehcache shiro xml 配置 首先securityManager配置 sessionManager配置
  • 并发编程概览

    由于内容较多 将会分成多篇文章详述 可移步查看 操作系统发展史 多道技术 进程理论 进程的并行与并发 进程的三状态 同步与异步 阻塞与非阻塞 同步异步与阻塞非阻塞 创建进程的多种方式 join方法 进程间数据默认隔离 进程间通信IPC机制
  • HashMap的十个经典问题

    整理了一些hashmap的一些经典问题 和大家分享一下 1 谈谈HashMap的一些特性 HashMap存储键值对实现快速存取 key值不可重复 但是允许为null 放在table 0 的位置 如果key值重复则覆盖 HashMap线程不安
  • 计算机科学与技术论文选题怎么选,比较好写的计算机科学与技术专业论文选题 计算机科学与技术专业论文题目如何取...

    100道 关于比较好写的计算机科学与技术专业论文选题汇总 作为大学生的毕业生应该明白了计算机科学与技术专业论文题目如何取 选一个好的题目后续的计算机科学与技术专业论文写作起来会更轻松 一 比较好写的计算机科学与技术专业论文题目 1 计算机科
  • 前端修行日记 --对象和数组的深浅拷贝方式

    对象的深浅拷贝方法 js类型介绍 首先js的数据值按照类型主要分为两大类 基本数据类型和引用数据类型 基本数据类型包括 Undefined Null Number String Boolean Symbol 引用数据类型则为Object 那
  • linux find 命令忽略某个或多个子目录的方法 【转】

    文章来源 linux find 命令忽略某个或多个子目录的方法 文章参考 使用find查找文件的时候怎么避开某个文件目录 在linux find 进行查找的时候 有时候需要忽略某些目录不查找 可以使用 prune 参数来进行过滤 但必须要注
  • Wireshark数据包分析——Teardrop泪滴攻击

    本文仅做数据包学习使用 一 泪滴攻击原理 Teardrop攻击是一种拒绝服务攻击 是一种针对IP协议的攻击方法 顾名思义 Teardrop攻击是一种令人落泪的攻击手段 可见其破坏威力很强大 它利用发送畸形数据包的方式 除此之外针对IP协议攻
  • Acwing 842. 排列数字

    dfs int u 搜索第u个位置上可以放哪个数字 include
  • linux下几种目标文件的分析

    本文中用到的命令 gcc c addvec c 生成可重定位目标文件addvec o readelf addvec o a 读取可重定位目标文件addvec o gcc O2 c main c 生成可重定位目标文件main o gcc st
  • wireshark怎么抓包和详细图文教程

    wireshark是非常流行的网络封包分析软件 功能十分强大 可以截取各种网络封包 显示网络封包的详细信息 使用wireshark的人必须了解网络协议 否则就看不懂wireshark了 为了安全考虑 wireshark只能查看封包 而不能修
  • iOS开发之内存管理

    iOS开发之内存管理 一 垃圾回收机制 二 内存管理的概念 三 OC内存管理注意事项 四 MRC相关语法 一 垃圾回收机制 与Java语言相同Objective c 2 0之后 也提供了垃圾回收机制 OC是支持垃圾回收机制的 Garbage