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图片上的线测量

    我需要一些帮助来开始绘制末端带有圆圈的线条 并测量其长度 我能够划清界限 但无法让它移动 花了几个小时决定在 SO 上发布 因此 请参阅下图并指导我开始 任何使用 Objective C 的示例或教程都会有帮助 谢谢 这个想法看起来实现起来
  • 签名根框架中嵌入的子框架不起作用(Xcode 11.2.1)

    我有一个小型的概念验证应用程序 我试图在我的框架 AequumPOCFramework framework 中嵌入 并签名 一个框架 Alamofire 但是 当我尝试部署到我的设备时 它不断给出我的错误 在使用库验证的进程中使用无效 映射
  • UITextField 中光标闪烁,但键盘不出现

    我得到了一个带有文本字段的简单详细视图 在详细的viewController中我写了这段代码 void viewDidAppear BOOL animated self textField becomeFirstResponder NSLo
  • 当设备方向改变时以编程方式更新约束的正确方法?

    我在用着storyboard and autolayout 并将 IB 中的约束设置为IBOutlet在相应的视图控制器中 我正在阅读几篇关于如何将纵向和横向的约束更新为不同的帖子 但我仍然不确定应该如何执行此操作 我应该设置新的限制吗 v
  • 允许在 Safari 上聊天应用程序使用 audio.play()

    由于苹果禁用了自动播放音频的功能HTMLMedia Element play https developer mozilla org en US docs Web API HTMLMediaElement play在没有用户交互的 java
  • iOS 13 UIActivityViewController 在图像保存后自动呈现以前的 VC

    我正在尝试实现 将图像保存到库 功能 然后返回到当前视图控制器 但在新的 iOS 13 上 它会返回到呈现当前视图控制器的视图控制器 PHPhotoLibrary requestAuthorization status PHAuthoriz
  • 如何在iOS应用程序中实现信号量?

    是否可以在ios应用程序中实现计数信号量 对的 这是可能的 有很多可用的同步工具 同步 NSLock NS条件 NS条件锁 GCD 信号量 并行线程锁 我建议阅读 线程编程指南 http developer apple com librar
  • Android 和 IOS 是否可以在后台发送短信?

    我想制作一个应用程序 其主要功能取决于发送短信 在我开发 android native 之前 但现在我使用 React Native 来为 IOS 和 Android 制作它 在 Android 中 如果获得用户许可 可以在后台发送短信 但
  • 为什么我的 Cordova/PhoneGap iOS 应用程序在设备旋转时不旋转?

    我正在尝试做一个仅横向应用程序 https stackoverflow com questions 10996676 phonegap page has wrong rotation shows as portrait in landsca
  • xib(Xcode8) 上 UIView/UIImageView 的大小变为 (1000, 1000)

    我在 xib 上使用自动布局来创建我的 UI 当我完成我的用户界面时 它在模拟器上运行良好 但是当我下次打开 Xcode8 时 xib 显示很奇怪 一些 UIView 和 UIImageView 变大 大小变为 1000 1000 即便如此
  • 为什么使用自动布局时视图的框架宽度始终为 600 x 600

    我正在制作一个基本的扫雷应用程序 用于快速练习 娱乐 我想让板的尺寸 10 个图块宽 适应任何 iOS 屏幕 为此 我通过获取tileContainer view frame width和 10来设置每个图块的大小 我的问题是 tileCo
  • 在 SwiftUI App 中实现深色模式切换

    我目前正在我的应用程序中研究深色模式 虽然由于我的 SwiftUI 基础 深色模式本身并不困难 但我正在努力选择将 ColorScheme 设置为独立于系统 ColorScheme 的选项 我在苹果人机界面指南中找到了这一点 https i
  • UIView 内的 UIButton 目标操作

    我有一个习惯UIView我创建了一个UIButton 在该视图中 我有以下代码 func setupViews menuControlButton addTarget self action toggleButton forControlE
  • 如何安全地将 CGFloat 降低或提高到 int?

    我经常需要在地板或天花板上安装CGFloat to an int 用于计算数组索引 我永远看到的问题floorf theCGFloat or ceilf theCGFloat 是浮点不准确可能会带来麻烦 那如果我的CGFloat is 2
  • xCode 7.1 中警报的 UITesting

    我正在 xCode 7 1 中编写 UITests 并且在测试警报时遇到问题 在我的情况下允许通知 创建测试时 xCode 会写入以下代码 app alerts U201cAppName U201d Would Like to Send Y
  • 从 iOS 中的 App Delegate 调用当前视图控制器中的方法

    我有两个视图控制器 BuildingsViewController 和 RoomsViewController 它们都使用应用程序委托中名为上传的函数 上传函数基本上执行一个 HTTP 请求 如果成功或不成功 都会触发 uialertvie
  • 滚动视图下的iOS swift 4 imageview:双击缩小

    我已经应用了图像视图来通过捏合来放大 缩小 那很容易 当在图像视图上应用双击时 无法检测到选择方法 我使用 Xcode 9 和 swift 4 您能告诉我滚动视图是否应该应用双击手势吗 var previewImage UIImage ni
  • 使用 twitterkit 将图像发布到 Twitter

    我正在尝试使用 Twitter 的新 TwitterKit 和自定义 UI 发布图像和推文 他们提供的唯一文档是如何用他们的观点来做这件事 所以我可以弄清楚如何在没有图像的情况下做到这一点 NSMutableDictionary messa
  • 在 swift 中从本地视频创建缩略图

    如何从本地视频文件快速创建缩略图 例如 如果视频文件路径位于此处 file Users Dev Library Developer CoreSimulator Devices F33222DF D8F0 448B A127 C5B03C64
  • cocos2d 2.0-rc2:结束director并重新启动

    我有一款由 cocos2d 驱动的游戏 它使用 UIKit 菜单 所以我只使用一个视图控制器的框架 即游戏本身 而且 它只有一个场景 从cocos2d 2 0开始 director本身就是一个UIViewController子类 所以我只是

随机推荐

  • 利用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