1. 程式人生 > >探討OC的記憶體管理 以及防止迴圈引用retain cycle 代理為什麼用weak block為什麼用copy

探討OC的記憶體管理 以及防止迴圈引用retain cycle 代理為什麼用weak block為什麼用copy

首先宣告OC的記憶體管理機制:引用計數。

當一個物件的引用計數為0時,這個物件就會被釋放。

銘記以上兩點,我們開始來探討。

換句話說,如果一個物件,沒有強指標指向,就會被釋放。

舉個很形象的例子,假如每一個物件都是一隻狗,每一個強指標都是狗鏈子,狗鏈子的數量就是引用計數。那麼情況就會變成這樣:當一個狗沒有被狗鏈子拴著的時候,它就跑了。哈哈~

那麼什麼情況下又會造成迴圈引用呢?顧名思義,就是兩個物件相互強引用,就會導致retain cycle.根據OC的記憶體管理機制,只有引用計數為0的時候物件才會被釋放。很顯然迴圈引用的直接結果就是導致兩個物件都釋放不掉造成記憶體洩漏。
舉一個非常簡單的迴圈引用的例子:

NSMutableArray *arr1 = [NSMutableArray array];
NSMutableArray *arr2 = [NSMutableArray array];
[arr1 addObjectsFromArray:arr2];
[arr2 addObjectsFromArray:arr1];

很明顯,arr1和arr2誰都不會被釋放,因為它們相互持有。
也是因此,代理屬性要宣告為assign或者weak,那同理,block也要注意迴圈引用。
但是代理和block宣告的時候是相反的,代理要用weak,block要用copy.

為什麼代理用weak或assign?

我們在ViewController.h中宣告一個委託,並寫一個代理屬性。
宣告代理屬性

然後在ViewController.m中呼叫代理
呼叫

在SecondViewController.m中遵守協議,併成為ViewController的代理,實現代理方法。
實現代理

上圖少了一行程式碼:[self.view addSubview:viewVC.view]這裡的重點是,viewVC.delegate = self; 這一行程式碼,這時,我們回看在ViewController中的代理屬性@property(nonatomic, weak) id delegate. 相當於這個id型別現在就是SecondViewController型別,換句話說,就是ViewController對SecondViewController進行了引用,這裡是weak,所以是弱引用。而SecondViewController對ViewController進行了強引用。


所以,如果delegate屬性宣告為strong,就會造成迴圈引用。

為什麼Block屬性用copy

記憶體分為五個區:棧區、堆區、常量區、程式碼區、靜態區(全域性區)。

Block用copy修飾可以拷貝到堆區,以便我們程式設計師管理。它本身預設是在棧區,由系統管理,什麼時候釋放不確定,為了避免訪問野指標,所以應該把它放在堆區。

注意:在ARC下,宣告出來的block屬性,不管用strong還是copy,編譯器都會對這個block進行copy操作。即便如此,還是推薦使用copy來修飾,這樣也能提醒你,編譯器會對block進行copy操作。

另一方面,block也會經常導致迴圈引用,所以通常的做法就是,在外部建立一個weakSelf(用__weak修飾的self),來防止迴圈引用。這裡最好在block內部再宣告一個strongSelf(用__strong來修飾weakSelf).這是因為保證程式碼在執行block期間,self不會被釋放,當block執行完後,會自動釋放該strongSelf;

相關推薦

探討OC記憶體管理 以及防止迴圈引用retain cycle 代理為什麼weak block為什麼copy

首先宣告OC的記憶體管理機制:引用計數。 當一個物件的引用計數為0時,這個物件就會被釋放。 銘記以上兩點,我們開始來探討。 換句話說,如果一個物件,沒有強指標指向,就會被釋放。 舉個很形象的例子,假如每一個物件都是一隻狗,每一個強指標都是狗鏈子

block使用時的一些情況以及防止迴圈引用

block 是在 iOS 4 中引入的新特性,蘋果官方推薦使用這種做法。 block 注意事項 1,block 在實現時就會對它引用到的它所在方法中定義的棧變數進行一次只讀拷貝,然後在 block 塊內使用該只讀拷貝。 如下程式碼: -(void)tes

android 記憶體管理以及優化 粗略方案

Android的記憶體管理方式 1.android系統記憶體分配和回收方式 一個app通常就是一個程序對應一個虛擬機器 通過adb shell 檢視應用的記憶體分配情況 ①通過ps來檢視系統內的程序 ②通過 dumpsys meminfo 包名  檢視對應的應用的記憶體

node之記憶體管理以及效能分析

node是v8引擎實現的,所以是v8的記憶體管理。涉及到的主要方法有: process.memoryUsage(),v8.getHeapSpaceStatistics(),v8.getHeapStatistics(),os.cpus(),os.totalmem();下面這個討論,在開始討論以前先說一下v8的

iOS容易造成迴圈引用的三種場景之Block以及對應的使用方法(二)

         可以看到在Block結構體中含有isa指標,這就證明了Block其實就是物件,並具有一般物件的所有功能。這個isa指標被初始化為_NSConcreteStackBlock或者_NSConcreteGlobalBlock類的地址。在沒有開啟ARC的情況下,如果Block中包含有區域性變數則is

block使用小結、在arc中使用block、如何防止迴圈引用

使用block已經有一段時間了,感覺自己瞭解的還行,但是幾天前看到CocoaChina上一個關於block的小測試主題 : 【小測試】你真的知道blocks在Objective-C中是怎麼工作的嗎?,發現竟然做錯了幾道, 才知道自己想當然的理解是錯誤的,所以抽時間學習了下,並且通過一些測試程式碼進行測試

iOS OC記憶體管理、ARC、property屬性、__strong、__weak、__block——iOS 編碼複習(一)

首先來聊聊記憶體管理。因為是先有了記憶體管理這個東西,才慢慢的有了ARC,而後才會有@property的各種屬性 聊到記憶體管理,我們就能知道iOS5之前,iOS的記憶體管理是MRC(手動記憶體管理)的。iOS5之後才有了ARC(自動記憶體管理)。 那我們就來看看MRC是怎

如何防止迴圈引用 assign

首先說下什麼是迴圈引用,迴圈引用是指兩個物件互相retain對方,通過OBJC的release是無法銷燬這兩個物件的。更嚴重的是,如果幾個物件間接相互引用,比如A<-B,B<-C,C<-A,那麼A、B、C都無法通過release釋放。例如下面的引用關係:•

iOS 防止迴圈引用的兩個方法

__block UITableViewController *weakself = self; [self.tableView addJElasticPullToRefreshViewWithActionHandler:^{

運用block防止迴圈引用

例如: [self.viewModel.titleSignal subscribeNext:^(NSString * title) { self.title = title; }]; 有迴圈引用的問題:self->viewM

黑馬程式設計師————OC記憶體管理_筆記整理(二)

一、@Prpperty引數 // 加上retain:表示生成的set方法,release舊值,retain新值 @property (retain) Book *book; // oc物件型別 //@property (nonatomic,retain) 類名 *屬性名

IOS知識分享:OC記憶體管理(黃金法則)

1、記憶體管理-黃金法則 The basic rule to apply is everything that increases the reference counter with alloc, [mutable]copy[withZone:] or retain

[黑馬程式設計師][OC]記憶體管理

一、記憶體管理的基本原理 1.什麼是記憶體管理 移動裝置的記憶體極其有限,每個app所能佔用的記憶體是有限制的,當app所佔用的記憶體較多時,系統會發出記憶體警告,這時得回收 一些不需要再使用的記憶體空間。比如回收一些不需要使用的物件、變數等。管理範圍:任何繼承了NS

黑馬程式設計師————OC記憶體管理_ARC

ARC( Autom Reference Counting) 是一個編譯器特性,會自動檢測幫我們release 一、ARC基本原理 1.編譯器特性 編譯程式碼的過程中會自動檢測哪裡需要插入自動釋放記憶體的程式碼 // 新建立一個物件,會自動釋放物件 P

PHP5和7中的zval全介紹,記憶體管理,型別,引用計數(1)

轉自:http://0x1.im/blog/php/Internal-value-representation-in-PHP-7-part-1.html 本文第一部分和第二均翻譯自Nikita Popov(nikic,PHP 官方開發組成員,柏林科技大學的學生)

黑馬程式設計師-----OC記憶體管理原則

------<a href="http://www.itheima.com" target="blank">Java培訓、Android培訓、iOS培訓、.Net培訓</a>、期待與您交流! ------- Objective-C對記憶體管理的方法

黑馬程式設計師——IOS基礎——OC記憶體管理

=====================引用計數器開始==================== 基本型別資料存放在棧中,物件存放在堆中 棧中的資料系統自動回收 堆空間中的資料動態分配,不能自動分配,容易引起記憶體洩露 需要給物件傳送訊息,讓它回收,即呼叫物件的回收方法

黑馬程式設計師--09 OC 記憶體管理

                           ------Java培訓、Android培訓、iOS培訓、.Net培訓、期待與您交流! ------- 1.管理範圍 任何繼承了NSObject的物件,對其他基本資料型別(int、char、float、double

小胖說swift07-------- swift協議代理的使用以及解決迴圈引用問題

這兩天看了一下Swift的協議代理, 大體思路和OC沒什麼區別, 但是按照官方的書本寫出的協議代理, 發現會有記憶體洩露問題, 找了半天沒有發現問題, 突然想起看系統類的協議代理的寫法, 瞬間發現了

linux記憶體管理之使用者態記憶體管理以及mmap

分配一個新的線性區 do_mmap =>ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT); =>len = PAGE