文档章节

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

gitzhengjianhua
 gitzhengjianhua
发布于 2016/07/23 16:36
字数 1192
阅读 40
收藏 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】定义@property时常用的修饰词介绍

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

浅浅青丘
06/13
0
0
IOS 浅谈闭包block的使用

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

周雨奇
07/23
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

没有更多内容

加载失败,请刷新页面

加载更多

laravel 微信支付

1.composer加载laravel微信支付第三方文件 composer require "overtrue/laravel-wechat:~4.0" composer require simplesoftwareio/simple-qrcode 1.3.* //composer生成二维码文件 2.改confi......

vio小黑
9分钟前
0
0
学习设计模式——抽象工厂模式

1. 认识抽象工厂模式 1. 定义:提供一个创建一系列相关或互相依赖的对象的接口,而无需指定它们具体的类。 2. 组成结构: AbstractFactory:抽象工厂类,定义创建一系列对象的操作接口 Fact...

江左煤郎
9分钟前
0
0
ES6的let块级作用域和变量不可提升导致一个比较容易出现的错误

今天在写NodeJS代码的时候出现一个变量一直提示未定义,简化后的代码如下: let param = 1;{ console.log(param);} 就在想,不至于啊。不是继承上层的声明吗? 继续看下去,发现原来...

MKjy
16分钟前
0
0
50:nginx访问日记|日记切割|静态文件不记录日记和过期时间

1、nginx访问日记: 日记格式:在主配置文件nginx.conf里搜索log_format; [root@localhost_001 conf]# vim nginx.conflog_format combined_realip '$remote_addr $http_x_forwarded_for ......

芬野de博客
19分钟前
0
0
前后端正常交互的流程

1、评审阶段:产品召集前后端进行需求评审,前后端各自捋清楚自己的业务量以及联调之间工作量,从而进行开发时间评估。 2、开发准备阶段:前后端一起商量需求中需要联调的部分,进行接口的口...

Jack088
19分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部