ARC下的內存泄漏

##ARC下的內存泄漏

ARC全稱叫 ARC(Automatic Reference Counting)。在編譯期間,編譯器會判斷對象的使用情況,并適當的加上retain和release,使得對象的內存被合理的管理。所以,從本質上說ARC和MRC在本質上是一樣的,都是通過引用計數的內存管理方式。ARC 的出現大大節省了程序員手動管理內存的時間成本,But,世上沒有完美的事物,我們也不要把任何事想的那么美好,在 ARC 環境下如果不注意的話也會引起內存泄漏。

目前在項目中引入了MLeaksFinder,能比較清晰的找到內存泄漏的位置。

##分析一下內存泄漏的主要原因

####循環引用(Retain Cycle)

什么是引用循環(retain cycle) ?假設我們有兩個實例A和B,B是A的一個strong型的property,則B的引用計數是1,當A的需要釋放的時候,A則會調用[B release]來釋放B,B的引用計數則減為0,釋放。

?可如果這時候將B的一個strong型property指向A,則A與B互相為強引用,問題就來了。因為B強引用A,A的引用計數永遠不會減為0,當A原本的強引用對象被釋放以后,A和B成為了一個相互引用的孤島,永遠不會被釋放了,這就會引起內存泄漏。

?在上面的例子中,就是一種非常普遍的引用循環情況,加入如上代碼的VC在dismiss或者pop以后,并不會執行dealloc方法,證明內存泄漏了。而引起泄漏的原因就是在作為self的property的block中,使用self指針導致self被block強引用,形成引用循環。

1、Delegate 我們在使用代理設計模式的時候,一定要注意將 delegate 變量聲明為 weak 類型,像這樣 @property (nonatomic, weak) id<xxxx> delegate; 如使用strong或別的類型修飾的話將會導致循環引用,導致dealloc()不會被調用。從而觸發一些意想不到的后果。

2、Block 目前在項目中出現的內存泄漏大部分是因為block的問題。 在 ARC 下,當 block 獲取到外部變量時,由于編譯器無法預測獲取到的變量何時會被突然釋放,為了保證程序能夠正確運行,讓 block 持有獲取到的變量,向系統聲明:我要用它,你們千萬別把它回收了!然而,也正因 block 持有了變量,容易導致變量和 block 的循環引用,造成內存泄露!

? ? [_sortButton setButtonSpreadPreAction:^BOOL{if (_resultItems.count == 0) {[progressHUD showText:@"xxxx"];return NO;}return YES;}];
復制代碼

這個例子的問題就在于在使用 block 的過程中形成了循環引用:self 持有 sortButton;sortButton 持有 block;block 持有 self。三者形成循環引用,內存泄露。

GCD已經一些系統級的API并不會提示循環引用的警告,但通過測試發現,大部分系統提供block也是需要弱引用的__weak typeof(self) weakSelf = self; 項目中除了AFN的第三方組件在調用block時都是需要弱引用的,如MJRefresh。

3、NSTimer ?NSTimer在VC釋放前,一定要調用[timer invalidate],不調用的后果就是NSTimer無法釋放其target,如果target正好是self,則會導致引用循環。

?這里要補充一點,引用循環不是只能有兩個對象,三個四個更多都是可以的,甚至環數也不一定只有一個,所以要養成良好的代碼習慣,在NSTimer停用前調用invalidate方法。

關于performSelector:afterDelay的問題

- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay
復制代碼

我們還是看看官方文檔怎么說的。 This method sets up a timer to perform the aSelector message on the current thread’s run loop. The timer is configured to run in the default mode (NSDefaultRunLoopMode). When the timer fires, the thread attempts to dequeue the message from the run loop and perform the selector. It succeeds if the run loop is running and in the default mode; otherwise, the timer waits until the run loop is in the default mode.

大概意思是系統依靠一個timer來保證延時觸發,但是只有在runloop在default mode的時候才會執行成功,否則selector會一直等待run loop切換到default mode。根據我們之前關于timer 的說法,在這里其實調用performSelector:afterDelay:同樣會造成系統對target強引用,也即retain住。這樣子,如果selector一直無法執行的話(比如runloop不是運行在default model下),這樣子同樣會造成target一直無法被釋放掉,發生內存泄露。怎么解決這個問題呢?其實很簡單,我們在適當的時候取消掉該調用就行了,系統提供了接口:

+ (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget
復制代碼

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/391347.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/391347.shtml
英文地址,請注明出處:http://en.pswp.cn/news/391347.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

python:校驗郵箱格式

# coding:utf-8import redef validateEmail(email):if re.match("^.\\(\\[?)[a-zA-Z0-9\\-\\.]\\.([a-zA-Z]{2,3}|[0-9]{1,3})(\\]?)$", email) ! None:# if re.match("/^\w[a-z0-9]\.[a-z]{2,4}$/", email) ! None:print okreturn okelse:print failret…

cad2019字體_這些是2019年最有效的簡歷字體

cad2019字體When it comes to crafting the perfect resume to land your dream job, you probably think of just about everything but the font. But font is a key part of your first impression to recruiters and employers.當制作一份完美的簡歷來實現理想的工作時&…

Go語言實戰 : API服務器 (4) 配置文件讀取及連接數據庫

讀取配置文件 1. 主函數中增加配置初始化入口 先導入viper包 import (..."github.com/spf13/pflag""github.com/spf13/viper""log")在 main 函數中增加了 config.Init(*cfg) 調用&#xff0c;用來初始化配置&#xff0c;cfg 變量值從命令行 f…

方差偏差權衡_偏差偏差權衡:快速介紹

方差偏差權衡The bias-variance tradeoff is one of the most important but overlooked and misunderstood topics in ML. So, here we want to cover the topic in a simple and short way as possible.偏差-方差折衷是機器學習中最重要但被忽視和誤解的主題之一。 因此&…

win10 uwp 讓焦點在點擊在頁面空白處時回到textbox中

原文:win10 uwp 讓焦點在點擊在頁面空白處時回到textbox中在網上 有一個大神問我這樣的問題&#xff1a;在做UWP的項目&#xff0c;怎么能讓焦點在點擊在頁面空白處時回到textbox中&#xff1f; 雖然我的小伙伴認為他這是一個 xy 問題&#xff0c;但是我還是回答他這個問題。 首…

python:當文件中出現特定字符串時執行robot用例

#coding:utf-8 import os import datetime import timedef execute_rpt_db_full_effe_cainiao_city():flag Truewhile flag:# 判斷該文件是否存在# os.path.isfile("/home/ytospid/opt/docker/jsc_spider/jsc_spider/log/call_proc.log")# 存在則獲取昨天日期字符串…

MySQL分庫分表方案

1. MySQL分庫分表方案 1.1. 問題&#xff1a;1.2. 回答&#xff1a; 1.2.1. 最好的切分MySQL的方式就是&#xff1a;除非萬不得已&#xff0c;否則不要去干它。1.2.2. 你的SQL語句不再是聲明式的&#xff08;declarative&#xff09;1.2.3. 你招致了大量的網絡延時1.2.4. 你失去…

linux創建sudo用戶_Linux終極指南-創建Sudo用戶

linux創建sudo用戶sudo stands for either "superuser do" or "switch user do", and sudo users can execute commands with root/administrative permissions, even malicious ones. Be careful who you grant sudo permissions to – you are quite lit…

重學TCP協議(1) TCP/IP 網絡分層以及TCP協議概述

1. TCP/IP 網絡分層 TCP/IP協議模型&#xff08;Transmission Control Protocol/Internet Protocol&#xff09;&#xff0c;包含了一系列構成互聯網基礎的網絡協議&#xff0c;是Internet的核心協議&#xff0c;通過20多年的發展已日漸成熟&#xff0c;并被廣泛應用于局域網和…

分節符縮寫p_p值的縮寫是什么?

分節符縮寫pp是概率嗎&#xff1f; (Is p for probability?) Technically, p-value stands for probability value, but since all of statistics is all about dealing with probabilistic decision-making, that’s probably the least useful name we could give it.從技術…

Spring-----AOP-----事務

xml文件中&#xff1a; 手動處理事務&#xff1a; 設置數據源 <bean id"dataSource" class"com.mchange.v2.c3p0.ComboPooledDataSource"> <property name"driverClass" value"com.mysql.jdbc.Driver"></property…

[測試題]打地鼠

Description 小明聽說打地鼠是一件很好玩的游戲&#xff0c;于是他也開始打地鼠。地鼠只有一只&#xff0c;而且一共有N個洞&#xff0c;編號為1到N排成一排&#xff0c;兩邊是墻壁&#xff0c;小明當然不可能百分百打到&#xff0c;因為他不知道地鼠在哪個洞。小明只能在白天打…

在PHP服務器上使用JavaScript進行緩慢的Loris攻擊[及其預防措施!]

Forget the post for a minute, lets begin with what this title is about! This is a web security-based article which will get into the basics about how HTTP works. Well also look at a simple attack which exploits the way the HTTP protocol works.暫時忘掉這個帖…

三星為什么要賣芯片?手機干不過華為小米,半導體好掙錢!

據外媒DigiTimes報道&#xff0c;三星有意向其他手機廠商出售自家的Exynos芯片以擴大市場份額。知情人士透露&#xff0c;三星出售自家芯片旨在提高硅晶圓工廠的利用率&#xff0c;同時提高它們在全球手機處理器市場的份額&#xff0c;尤其是中端市場。 三星為什么要賣芯片&…

重學TCP協議(2) TCP 報文首部

1. TCP 報文首部 1.1 源端口和目標端口 每個TCP段都包含源端和目的端的端口號&#xff0c;用于尋找發端和收端應用進程。這兩個值加上IP首部中的源端IP地址和目的端IP地址唯一確定一個TCP連接 端口號分類 熟知端口號&#xff08;well-known port&#xff09;已登記的端口&am…

linux:vim中全選復制

全選&#xff08;高亮顯示&#xff09;&#xff1a;按esc后&#xff0c;然后ggvG或者ggVG 全部復制&#xff1a;按esc后&#xff0c;然后ggyG 全部刪除&#xff1a;按esc后&#xff0c;然后dG 解析&#xff1a; gg&#xff1a;是讓光標移到首行&#xff0c;在vim才有效&#xf…

機器學習 預測模型_使用機器學習模型預測心力衰竭的生存時間-第一部分

機器學習 預測模型數據科學 &#xff0c; 機器學習 (Data Science, Machine Learning) 前言 (Preface) Cardiovascular diseases are diseases of the heart and blood vessels and they typically include heart attacks, strokes, and heart failures [1]. According to the …

程序2:word count

本程序改變自&#xff1a;http://blog.csdn.net/zhixi1050/article/details/72718638 語言&#xff1a;C 編譯環境&#xff1a;visual studio 2015 運行環境&#xff1a;Win10 做出修改的地方&#xff1a;在原碼基礎上修改了記錄行數的功能&#xff0c;刪去了不完整行數的記錄&…

重學TCP協議(3) 端口號及MTU、MSS

1. 端口相關的命令 1.1 查看端口是否打開 使用 nc 和 telnet 這兩個命令可以非常方便的查看到對方端口是否打開或者網絡是否可達。如果對端端口沒有打開&#xff0c;使用 telnet 和 nc 命令會出現 “Connection refused” 錯誤 1.2 查看監聽端口的進程 使用 netstat sudo …

Diffie Hellman密鑰交換

In short, the Diffie Hellman is a widely used technique for securely sending a symmetric encryption key to another party. Before proceeding, let’s discuss why we’d want to use something like the Diffie Hellman in the first place. When transmitting data o…