文档章节

ios--内存管理strong和weak的简单理解

gitzhengjianhua
 gitzhengjianhua
发布于 2016/07/23 16:36
字数 1192
阅读 36
收藏 1

如果在网上搜关于内存管理最多的总结就是谁持有谁释放。但是内存管理往多的说是有好多东西的,我今天只写一下关于strong、weak和autoreleas(以后会写片博客,会介绍到它们的底层运作)。在此也给想更深入了解的伙伴们推荐本书一个日本前辈写的Objective-C高级编程,我自己讲内存管理梳理的差不多清晰的时,多亏了它。

关于内存管理,我原来有一段时间都对strong、weak傻傻的区分不清楚,也没有多少兴趣去了解。直到一天我真的在使用代理中碰到了神奇的内存泄漏,害死我了,经过调查锁定了凶手就是weak,根本的罪魁祸首是我对修饰符使用的一知半解。希望这点理解能起到一点点帮助。

a、区分strong、weak

strong:strong为强引用,是id类型对象和对象默认的所有权修饰符(我们平时在@property中指定了属性的修饰strong、weak、或者是assign,但是在创建其他对象的时候,系统帮我们默认加了_strong修饰符进行内存管理),使用strong修饰的对象在超出其变量作用域时,即该变量被废弃时,会释放其被赋予的对象。使用strong会对对象被持有对象的引用计数产生影响,当其持用一其他对象的时候,会将其他对象的引用计数加1,当出作用域强引用失效时,会释放掉对其持有对象的持有。

weak:weak为若引用。weak修饰的对象,当其持有其他对象的时候不会对其他对象的引用计数造成影响,weak的存在很好的解决掉了循环引用。当它所持有的对象销毁时,weak修饰的对象会自动置nil。关于weak的实现我简单的多说一点,因为我自己原来对此很好奇然后多方了解了下,在此分享给大家,如果有错欢迎更希望大家纠正。

runtime会对注册的类进行布局,对于weak对象会放入一个hash表中。使用weak对象的内存地址作为key,当weak对象指向的对象的引用计数为0的时候执行置nil。执行过程为以weak对象的内存地址为索引,在hash表中找到对应的weak修饰对象,将其置为nil。

b、作用的区分

讨论他两避免不了循环引用和自引用。说白了就是光使用strong容易出现内存泄漏即在对象出了作用域(也就是大括号)后不能得到释放。如下例子:

分别创建对象a、b,他们分别被对象A、B持有(当我们没有指定修饰权时,我们创建的对象默认的修饰权为_strong,也就是强引用)。然后对象B中有个成员变量objB又持有了a一次,对象A中的成员变量abjA有持有了b一次。这样,就会形成循环引用。因为在出了作用域后A、B的强引用失效,释放掉了对a、b的持有,但是他们中的成员变量并没有释放掉对于a、b的持有。此时发生内存泄漏,也就是我们所说的循环引用。

上面刚刚说过,weak不会对引用计数造成影响,也就不会影响到有关对象的释放。所以我们在关键部位使用weak修饰并不会造成对有关对象的引用计数造成影响,从而使得已经出了作用域但是有关该释放的对象并不能得到释放,造成内存泄漏。

c、autoreleas有关问题

之所以说autoreleas是因为原先在网上学习内存管理这块的时候被误导过,在此希望大家注意。autoreleas释放池中对对象的释放我原来好奇过,上网查的时候最后形成的答案是作用域。但是随着对O-C更加深入的学习,发现了它对于其内部寄存对象的释放是和runloop有关系的。

iOS程序由许多的runloop组成,每一个runloop都会有一个Autorelease Pool并在末尾进行释放。

比如我们点击一个button,一个button从等待到点击到响应就存在一次循环,期间就前程到对象的创建和最后Autorelease Pool在runloop即将结束时的销毁全部对象。

© 著作权归作者所有

共有 人打赏支持
gitzhengjianhua

gitzhengjianhua

粉丝 4
博文 25
码字总数 23833
作品 3
渭南
加载中

评论(1)

Kavana达达
Kavana达达
看了您关于AVAssetReader生成波形的文章,写得相当好,代码精简,受益匪浅.最近研究fft,希望跟您交个朋友.我的qq是20719414请多包含.
Xcode ARC需要什么版本的环境支持

Mac OS X v10.6 和 v10.7 (64位应用) 的Xcode 4.2以上版本支持ARC,iOS 4 和 iOS 5 下ARC都能工作,但Weak不支持Mac OS X v10.6 和 iOS 4,所以要想在iOS 4下运行用ARC的程序,只能用strong。...

东方皓
2013/05/06
0
0
IOS 浅谈闭包block的使用

前言:对于ios初学者,block通常用于逆向传值,遍历等,会使用,但是可能心虚,会感觉block很神秘,那么下面就一起来揭开它的面纱吧。 ps: 下面重点讲叙了闭包的概念,常用的语法,以及访问变...

周雨奇
07/23
0
0
【iOS】定义@property时常用的修饰词介绍

iOS编程中,定义成员变量常用格式如下: 常用的修饰词有atomic,nonatomic,copy,assign,strong,weak,readonly,readwrite等。面试中也会常常被问到这些修饰词的含义及其之间的区别,其本...

浅浅青丘
06/13
0
0
iOS中结合代码看内存管理(一)

阅读本文前,建议移步先去了解下内存管理相关知识。 1: iOS内存管理机制(百度goole大法可以获得很多推荐)。 2: iOS中的动态内存分配 3: 堆栈的原理:堆栈 百科 1:自动释放池的常见问题: ...

Nlinger
2017/06/07
0
0
Objective-C 之 @property和@synthesize

我用了不到一周的时间学习了Objective-C,后面的大部分时间我都在了解如何使用IOS的SDK和一些高级的话题,到目前已经有两个多月的时间了。目前能做一些简单的应用,但是在写代码的时候明显感...

XMAN2017
2013/04/29
0
11

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Spring Cloud Gateway真的有那么差吗?

前言 Spring Cloud从一开始最受大家质疑的就是网关性能,那是由于Spring Cloud最初选择了使用Netflix几年前开源的Zuul作为基础,而高性能版的Zuul 2在经过了多次跳票之后,对于Spring这样的整...

Java小铺
43分钟前
1
0
SpringBoot远程调试,远程debug你的线上项目

开发环境中代码出错了,可以利用IDE的debug功能来进行调试。那线上环境出错呢? 一、假设我们的项目是部署在tomcat中,那我们就需要对tomcat进行一定对配置,配置如下。 1. windows系统中,找...

nonnetta
48分钟前
0
0
JAVA秒杀优化方向

秒杀优化方向 将请求尽量拦截在系统上游:传统秒杀系统之所以挂,请求都压倒了后端数据层,数据读写锁冲突严重,几乎所有请求都超时,流量虽大,下单成功的有效流量甚小,我们可以通过限流、...

小贱是个程序员
55分钟前
0
0
C# 统计字符串中大写字母和小写字母的个数

static void Main() { int count1 = 0; int count2 = 0; Console.WriteLine("请输入字符串"); string str = Convert.ToString(Consol......

熊二的爸爸是谁
57分钟前
0
0
分布式服务框架之远程通讯技术及原理分析

在分布式服务框架中,一个最基础的问题就是远程服务是怎么通讯的,在Java领域中有很多可实现远程通讯的技术,例如:RMI、MINA、ESB、Burlap、Hessian、SOAP、EJB和JMS等,这些名词之间到底是...

老道士
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部