首页 > 其他分享 >关于ARC的介绍和ARC与MRC混编解决

关于ARC的介绍和ARC与MRC混编解决

时间:2022-12-08 14:06:09浏览次数:66  
标签:指向 对象 weak 混编 ARC MRC strong 指针


1. ARC & MRC 混合开发

在项目开发中,遇到使用MRC开发的第三方库怎么办?

例如:ASI

1> 尝试使用Xcode的转换工具(失败率比较高)

2> 在编译选项中,为MRC的程序添加-fno-objc-arc标记,表明在编译时,该文件使用MRC编译

​​

备注:

(1) 演示中使用的RegexKitLite还需要导入libicucore.dylib动态库

(2) 如果要在MRC项目中添加ARC的文件,可以使用 -fobjc-arc 标记即可

​​

3> 将MRC的第三方库直接编译成静态库使用

注意:在编译静态库时,不能添加动态库引用

说明:

RegexKitLite是对NSString添加的正则表达式分类

在项目中,如果使用的静态库中包含分类,则需要在Other Link Flag中添加 -ObjC选项

什么是ARC?

Automatic Reference Counting,自动引用计数,即ARC,可以说是WWDC2011和iOS5所引入的最大的变革和最激动人心的变化。ARC是新的​LLVM​ 3.0编译器的一项特性,使用ARC,可以说一举解决了广大iOS开发者所憎恨的手动内存管理的麻烦。

ARC机制

学习ARC很简单,在MRC时代你需要自己retain一个想要保持的对象,而现在不需要了。现在唯一要做的是用一个指针指向这个对象,只要指针没有被置空,对象就会一直保持在堆上。当将指针指向新值时,原来的对象会被release一次。这对实例变量,sunthesize的变量或者局部变量都是适用的。比如



  1. NSString *firstName = self.textField.text; 

firstName现在指向NSString对象,这时这个对象(textField的内容字符串)将被hold住。比如用字符串@“OneV”作为例子,这个时候firstName持有了@”OneV”。

关于ARC的介绍和ARC与MRC混编解决_内存机制

当然,一个对象可以拥有不止一个的持有者(这个类似MRC中的retainCount>1的情况)。在这个例子中显然self.textField.text也是@“OneV”,那么现在有两个指针指向对象@”OneV”(被持有两次,retainCount=2,其实对NSString对象说retainCount是有问题的,不过anyway~就这个意思而已.)。

关于ARC的介绍和ARC与MRC混编解决_内存机制_02

过了一会儿,也许用户在textField里输入了其他的东西,那么self.textField.text指针显然现在指向了别的字符串,比如@“onevcat”,但是这时候原来的对象已然是存在的,因为还有一个指针firstName持有它。现在指针的指向关系是这样的:

关于ARC的介绍和ARC与MRC混编解决_ARC_03

只有当firstName也被设定了新的值,或者是超出了作用范围的空间(比如它是局部变量但是这个方法执行完了或者它是实例变量但是这个实例被销毁了),那么此时firstName也不再持有@“OneV”,此时不再有指针指向@”OneV”,在ARC下这种状况发生后对象@”OneV”即被销毁,内存释放。

关于ARC的介绍和ARC与MRC混编解决_ios开发_04

类似于firstName和self.textField.text这样的指针使用关键字”strong”进行标志,它意味着只要该指针指向某个对象,那么这个对象就不会被销毁。反过来说,ARC的一个基本规则即使,只要某个对象被任一strong指针指向,那么它将不会被销毁。如果对象没有被任何strong指针指向,那么就将被销毁。在默认情况下,所有的实例变量和局部变量都是strong类型的。可以说strong类型的指针在行为上和MRC时代retain的property是比较相似的。

既然有”strong”,那肯定有”weak”咯~weak类型的指针也可以指向对象,但是并不会持有该对象。比如:



  1. __weak NSString *weakName = self.textField.text 

得到的指向关系是:

关于ARC的介绍和ARC与MRC混编解决_内存机制_05

这里声明了一个weak的指针weakName,它并不持有@“onevcat”。如果self.textField.text的内容发生改变的话,根据之前提到的“只要某个对象被任一strong指针指向,那么它将不会被销毁。如果对象没有被任何strong指针指向,那么就将被销毁”原则,此时指向@“onevcat”的指针中没有strong类型的指针,@”onevcat”将被销毁。同时,在ARC机制作用下,所有指向这个对象的weak指针将被置为nil。这个特性相当有用,相信无数的开发者都曾经被指针指向已释放对象所造成的EXC_BAD_ACCESS困扰过,使用ARC以后,不论是strong还是weak类型的指针,都不再会指向一个dealloced的对象,从根源上解决了意外释放导致的crash。

关于ARC的介绍和ARC与MRC混编解决_ARC_06

不过在大部分情况下,weak类型的指针可能并不会很常用。比较常见的用法是在两个对象间存在包含关系时:对象1有一个strong指针指向对象2,并持有它,而对象2中只有一个weak指针指回对象1,从而避免了循环持有。一个常见的例子就是oc中常见的delegate设计模式,viewController中有一个strong指针指向它所负责管理的UITableView,而UITableView中的dataSource和delegate指针都是指向viewController的weak指针。可以说,weak指针的行为和MRC时代的assign有一些相似点,但是考虑到weak指针更聪明些(会自动指向nil),因此还是有所不同的。细节的东西我们稍后再说。

关于ARC的介绍和ARC与MRC混编解决_MRC_07

注意类似下面的代码似乎是没有什么意义的:



  1. __weak NSString *str = [[NSString alloc] initWithFormat:…];  
  2.        
  3. NSLog(@"%@",str); //输出是"(null)"

由于str是weak,它不会持有alloc出来的NSString对象,因此这个对象由于没有有效的strong指针指向,所以在生成的同时就被销毁了。如果我们在Xcode中写了上面的代码,我们应该会得到一个警告,因为无论何时这种情况似乎都是不太可能出现的。你可以把weak换成strong来消除警告,或者直接前面什么都不写,因为ARC中默认的指针类型就是strong。

property也可以用strong或weak来标记,简单地把原来写retain和assign的地方替换成strong或者weak就可以了。



  1. @property (nonatomic, strong) NSString *firstName;  
  2.         
  3. @property (nonatomic, weak) id  delegate; 

ARC可以为开发者节省很多代码,使用ARC以后再也不需要关心什么时候retain,什么时候release,但是这并不意味你可以不思考内存管理,你可能需要经常性地问自己这个问题:谁持有这个对象?

比如下面的代码,假设array是一个NSMutableArray并且里面至少有一个对象:



  1. id obj = [array objectAtIndex:0];  
  2.       
  3. [array removeObjectAtIndex:0];  

  4. NSLog(@"%@",obj); 

在MRC时代这几行代码应该就挂掉了,因为array中0号对象被remove以后就被立即销毁了,因此obj指向了一个dealloced的对象,因此在NSLog的时候将出现EXC_BAD_ACCESS。而在ARC中由于obj是strong的,因此它持有了array中的首个对象,array不再是该对象的唯一持有者。即使我们从array中将obj移除了,它也依然被别的指针持有,因此不会被销毁。



标签:指向,对象,weak,混编,ARC,MRC,strong,指针
From: https://blog.51cto.com/u_15894905/5921061

相关文章

  • ARC145~152 题解
    比赛标号从大到小排列.因为博主比较菜所以没有题解的题都是博主不会做的/youlARC144以前的比赛懒得写了.目录AtCoderRegularContest152B.PassonPathC.PivotD......
  • docker search docker images --no-trunc --no-stream
    dockersearchdockerimages--no-trunc--no-streamdenied:requestedaccesstotheresourceisdenieddocker上传镜像命名tag时需要匹配 仓库名 ......
  • 初次搭建win下的elasticsearch环境
    搭建这个环境,当然是为了elk啦只是搭建这个环境暗藏了几个坑 1.启动Elasticsearch时报错java.nio.file.NoSuchFileException\lib\dt.jar这个问题是因为本机上安装......
  • ArcGIS插件-太乐地图
    在很多行业,打败你的往往不是竞争对手,而是你意想不到的其他因素。回想十年前,如果能预料到现在的处境,也许当时的心态和做法会有所不同。在多年前,市场上出现包括水经注、太乐......
  • elasticsearch中如何实现dinstinct去重功能
    一、功能场景在mysql数据库中查询数据时,我们可以采用dinstinct关键字去重。那么,在ES中如何实现查询结果去重呢?二、原理分析DISTINCT关键字去重的sql语句等价于对需要去重的......
  • SpringBoot整合elasticsearch-rest-client实战
    前言很多人在Springboot项目中都已经习惯采用Spring家族封装的spring-data-elasticsearch来操作elasticsearch,而官方更推荐采用rest-client。今天给大家介绍下在springbo......
  • 全网最详细elasticsearch7.10.2安装手册
    前言网上关于elasticsearch的安全教程很多,但是只是局限在最基础的启动就成功就完了。今天给大家分享elasticsearch7.10.2最全安装手册,记录自己踩过的一些坑。一、环境说明服......
  • 还不会ES?Elasticsearch快速入门实操指南送上
    前言本文主要介绍ES的常用请求,让大家能快速上手ES的使用主要参考官网的​​Quickstart​​指引。一、请求方式向Elasticsearch发送请求主要有2种方式:1、使用restapi发送h......
  • elasticsearch安装和使用
    下载地址:https://www.elastic.co/cn/downloads/past-releases#elasticsearch    https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.10.1-......
  • ArcMap图表有黑边
    问题描述在写作业的时候,忽然发现把图表插入到布局视图时,图象周围会有黑边出现,在调整大小时,仍无法消除黑边。解决方法方法一我的ArcGIS版本为10.2.2。我的软件出......