国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - IOS - IOS中內存管理那些事

IOS中內存管理那些事

2020-12-28 11:18iOS開發網 IOS

這篇文章主要介紹了IOS中內存管理那些事的相關資料,需要的朋友可以參考下

objective-c 和 swift 語言的內存管理方式都是基于引用計數「reference counting」的,引用計數是一個簡單而有效管理對象生命周期的方式。引用計數分為手動引用計數「arc: automaticreference counting」和自動引用計數「mrc: manual reference counting」,現在都是用 arc 了,但是我們還是很有必要了解 mrc。

1. 引用計數的原理是什么?

當我們創建一個新對象時,他的引用計數為1;

當有一個新的指針指向這個對象時,他的引用計數就加1;

當對象關聯的某個指針不再指向他時,他的引用計數就減1;

當對象的引用計數為0時,說明此對象不再被任何指針指向,這時我們就可以將對象銷毀,回收內存。

由于引用計數簡單有效,除了 objective-c 語言外,microsoft 的 com「component object model」、c++11(基于引用計數的智能指針 share_prt)等語言也提供了基于引用計數的內存管理方式。

IOS中內存管理那些事

舉個例子:

新建工程,xcode 默認開啟的是 arc,我們這里針對「appdelegate.m」文件使用 mrc,進行以下配置:

選擇目標工程,然后在「build phases」的「compile sources」下的「appdelegate.m」文件配置編譯器參數「compiler flags」值為「-fno-objc-arc」

IOS中內存管理那些事

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
- (bool)application:(uiapplication *)application didfinishlaunchingwithoptions:(nsdictionary *)launchoptions {
  nsobject *objo = [nsobject new];
  nslog(@"reference count: %lu", (unsigned long)[objo retaincount]); // 1
  nsobject *objb = [objo retain];
  nslog(@"reference count: %lu", (unsigned long)[objo retaincount]); // 2
  [objo release];
  nslog(@"reference count: %lu", (unsigned long)[objo retaincount]); // 1
  [objo release];
  nslog(@"reference count: %lu", (unsigned long)[objo retaincount]); // 1
  
  [objo setvalue:nil forkey:@"test"]; // 僵尸對象,向野指針發送消息會報錯(exc_bad_access)
  
  return yes;
}

 

IOS中內存管理那些事

xcode 默認不會監控僵尸對象,這里我們配置開啟他,然后就可以看到具體的跟蹤信息了:

IOS中內存管理那些事

 

IOS中內存管理那些事

也可以通過選擇「product」下的「profile」來打開「instruments」工具集。然后選擇「zombies」,再單擊右下角的「choose」按鈕進入檢測界面,這時點擊左上角的「record」紅色圓點按鈕開始檢測。

IOS中內存管理那些事

 

IOS中內存管理那些事

1.1 上面例子,為什么最后一次通過 retaincount 獲取的值為1,而不是為0呢?

因為該對象的內存已經被回收,我們向一個被回收的對象發送 retaincount 消息,他的輸出結果是不確定的,如果該對象所占內存被復用了,那么就可能造成程序異常崩潰。

而且當最后一次執行 release 時,系統已經知道馬上要回收內存了,就沒必要再將 retaincount 減1,因為不管減不減1,該對象都會被回收,回收后他所在內存區域(包括 retaincount 值)就沒有意義了。不將retaincount 減1變為0,可以減少一次內存操作,加快對象的回收。

 

1.2 什么是僵尸對象、野指針、空指針呢?

僵尸對象:所占用內存已經被回收的對象,僵尸對象不能再使用。

野指針:指向僵尸對象(不可用內存)的指針,給野指針發送消息會報錯(exc_bad_access)。

空指針:沒有指向任何對象的指針(存儲的是 nil、null),給空指針發送消息不會報錯;空指針的一個經典使用場景就是在開發中獲取服務器 api 數據時,轉換野指針為空指針,避免發送消息報錯。

 

2. 為什么需要引用計數?

從上面簡單例子,我們還看不出引用計數真正的用處,因為該對象的生命周期只是在一個方法內。在真實的應用場景中,我們在方法內使用臨時對象,通常不需要修改他的引用計數,只需要在方法返回前銷毀對象就可以了。

然而,引用計數真正派上用場的場景是在面向對象的程序設計架構中,用于對象之間傳遞和共享數據。

 

舉個例子:

假如對象 a 生成了一個對象 o,需要調用對象 b 的某個方法,將對象 o 作為參數傳遞過去。

在沒有引用計數的情況下,一般內存管理的原則是「誰申請誰釋放」,那么對象 a 就需要在對象 b 不再需要對象 o 的時候,將對象 o 銷毀。但對象 b 可能臨時用一下對象 o,也可以覺得他重要,將他設置為自己的一個成員變量,在這種情況下,什么時候銷毀對象 o 就成了一個難題了。

IOS中內存管理那些事

對于以上情況有兩種做法:

(1)對象 a 在調用完對象 b 的某個方法之后,馬上銷毀參數對象 o,然后對象 b 需要將對象 o 復制一份,生成另一個對象 o2,同時自己來管理對象 o2 的生命周期。但是這種做法有一個很大的問題,就是他帶來更多的內存申請、復制、釋放的工作。本來可以復用的對象,因為不方便管理他的生命周期,就簡單地把他銷毀,又重新構造一份一樣的,實在太影響性能。

(2)對象 a 只負責生成對象 o,之后就由對象 b 負責完成對象 o 的銷毀工作。如果對象 b 只是臨時用一下對象 o,就可以用完后馬上銷毀,如果對象 b 需要長時間使用對象 o,就不銷毀他。這種做法看似解決了對象復制的問題,但是他強烈依賴于 a 和 b 兩個對象的配合,代碼維護者需要明確地記住這種編程約定。而且,由于對象 o 的生成和釋放在不同對象中,使得他的內存管理代碼分散在不同對象中,管理起來也很費勁。如果這個時候情況更加復雜一些,例如對象 b 需要再向對象 c 傳遞參數對象 o,那么這個對象在對象 c 中又不能讓對象 c 管理。所以這種方法帶來的復雜度更高,更加不可取。

IOS中內存管理那些事

引用計數的出現很好地解決這個問題,在參數對象 o 的傳遞過程中,哪些對象需要長時間使用他,就把他的引用計數加1,使用完就減1。所有對象遵守這個規則,對象的生命周期管理就可以完全交給引用計數了。我們也可以很方便地享受到共享對象帶來的好處。

2.1 什么是循環引用「reference cycles」問題,怎么解決呢?

引用計數這種內存管理方式雖然簡單,但有一個瑕疵就是他不能自動解決循環引用的問題。

舉個例子:

對象 a 和對象 b 相互引用對方作為自己的成員變量,只有當自己銷毀時,才將自己的成員變量的引用計數減1,因為對象 a 和對象 b 的銷毀相互依賴,這樣就造成我們所說的循環引用問題了。

循環引用會導致即使外界已經沒有任何指針能夠訪問他們了,但是他們所占資源仍然無法釋放的情況。

IOS中內存管理那些事

解決循環引用問題主要有兩種方法:

(1)明確知道哪里存在循環引用,合理時機主動斷開環中的一個引用,使得對象得以回收。這種方法不常用,因為他依賴開發人員自己手工顯式控制,相當于回到以前「誰申請誰釋放」的內存管理年代。

(2)使用弱引用「weak reference」,「weak」「__weak」類型,這種方法常用。弱引用雖然持有對象,但是并不增加他的引用計數。弱引用的一個經典使用場景就是委托代理「delegate」協議模式。

 

2.2 xcode 中有什么工具可以檢測循環引用嗎?

在 xcode 中有「instruments」工具集可以很方便地檢測循環引用。

舉個例子:

 

?
1
2
3
4
5
6
7
8
- (void)viewdidload {
  [super viewdidload];
  
  nsmutablearray *marrfirst = [nsmutablearray array];
  nsmutablearray *marrsecond = [nsmutablearray array];
  [marrfirst addobject:marrsecond];
  [marrsecond addobject:marrfirst];
}

可以選擇「product」下的「profile」來打開「instruments」工具集。

IOS中內存管理那些事

然后選擇「leaks」,再單擊右下角的「choose」按鈕進入檢測界面,這時點擊左上角的「record」紅色圓點按鈕開始檢測。

IOS中內存管理那些事

 

IOS中內存管理那些事

 

IOS中內存管理那些事

 

IOS中內存管理那些事

 

IOS中內存管理那些事

3. core foundation 對象的內存管理

arc 是編譯器特性,他不是運行時特性,更不是垃圾回收器「gc」。

arc 能夠解決 ios 開發中90%的內存管理問題,但是另外10%的內存管理問題是需要開發人員自己處理的,這主要是與底層 core foundation 對象交互的部分,底層 core foundation 對象由于不在 arc 的管理下,所以需要自己維護這些對象的引用計數。

實際上 core foundation 對象使用的 cfretain 和 cfrelease 方法,可以認為與 objective-c 對象的 retain 和 release 方法等價,所以我們可以以 mrc 的方式進行類似管理。

 

3.1 在 arc 中,通過什么方式可以把 core foundation 對象轉換為 objective-c 對象呢?

轉換的過程,其實是告訴編譯器,對象的引用計數如何調整。

這里我們可以使用橋接「bridge」相關關鍵字來進行轉換工作,以下是這些(雙下劃線)關鍵字的說明:

(1)__bridge:只做類型轉換,不修改相關對象的引用計數,原來的 core foundation 對象在不用時,需要調用 cfrelease 方法。

(2)__bridge_retained:類型轉換后,將相關對象的引用計數加1,原來的 core foundation 對象在不用時,需要調用 cfrelease 方法。

(3)__bridge_transfer:類型轉換后,將相關對象的引用計數交給 arc 管理,原來的 core foundation 對象在不用時,不需要調用 cfrelease 方法。

 

我們根據具體的業務邏輯,合理使用上面的三種轉換關鍵字,就可以解決core foundation 對象 與 objective-c 對象相對轉換的問題了。

延伸 · 閱讀

精彩推薦
  • IOSiOS開發之視圖切換

    iOS開發之視圖切換

    在iOS開發中視圖的切換是很頻繁的,獨立的視圖應用在實際開發過程中并不常見,除非你的應用足夠簡單。在iOS開發中常用的視圖切換有三種,今天我們將...

    執著丶執念5272021-01-16
  • IOSiOS中MD5加密算法的介紹和使用

    iOS中MD5加密算法的介紹和使用

    MD5加密是最常用的加密方法之一,是從一段字符串中通過相應特征生成一段32位的數字字母混合碼。對輸入信息生成唯一的128位散列值(32個字符)。這篇文...

    LYSNote5432021-02-04
  • IOSiOS中UILabel實現長按復制功能實例代碼

    iOS中UILabel實現長按復制功能實例代碼

    在iOS開發過程中,有時候會用到UILabel展示的內容,那么就設計到點擊UILabel復制它上面展示的內容的功能,也就是Label長按復制功能,下面這篇文章主要給大...

    devilx12792021-04-02
  • IOSiOS中滑動控制屏幕亮度和系統音量(附加AVAudioPlayer基本用法和Masonry簡單使用)

    iOS中滑動控制屏幕亮度和系統音量(附加AVAudioPlayer基本用法和

    這篇文章主要介紹了iOS中滑動控制屏幕亮度和系統音量(附加AVAudioPlayer基本用法和Masonry簡單使用)的相關資料,需要的朋友可以參考下...

    CodingFire13652021-02-26
  • IOSiOS開發技巧之狀態欄字體顏色的設置方法

    iOS開發技巧之狀態欄字體顏色的設置方法

    有時候我們需要根據不同的背景修改狀態欄字體的顏色,下面這篇文章主要給大家介紹了關于iOS開發技巧之狀態欄字體顏色的設置方法,文中通過示例代碼...

    夢想家-mxj8922021-05-10
  • IOSiOS自定義UICollectionViewFlowLayout實現圖片瀏覽效果

    iOS自定義UICollectionViewFlowLayout實現圖片瀏覽效果

    這篇文章主要介紹了iOS自定義UICollectionViewFlowLayout實現圖片瀏覽效果的相關資料,需要的朋友可以參考下...

    jiangamh8882021-01-11
  • IOSiOS實現控制屏幕常亮不變暗的方法示例

    iOS實現控制屏幕常亮不變暗的方法示例

    最近在工作中遇到了要將iOS屏幕保持常亮的需求,所以下面這篇文章主要給大家介紹了關于利用iOS如何實現控制屏幕常亮不變暗的方法,文中給出了詳細的...

    隨風13332021-04-02
  • IOS詳解iOS中多個網絡請求的同步問題總結

    詳解iOS中多個網絡請求的同步問題總結

    這篇文章主要介紹了詳解iOS中多個網絡請求的同步問題總結,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧...

    liang199111302021-03-15
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 欧美九九九 | 亚洲欧洲视频 | 日韩电影一区 | 一区二区三区在线 | 亚洲成人久久久 | 亚洲高清电影 | 日韩一区二区在线观看 | 久久精品国产清自在天天线 | 亚洲精品国产a | 综合久久99 | 成人av网站在线观看 | 激情五月婷婷av | 午夜视频网站 | 久久中文视频 | 亚洲精品久久 | 日本一区高清 | 成人亚州 | 激情五月婷婷 | 午夜影院在线观看 | 成人精品在线视频 | 久免费视频 | 日本激情网 | 91视频8mav | 91丨九色丨国产 | 国内外成人激情免费视频 | 四虎视频 | 日韩一级精品视频在线观看 | 6080亚洲精品一区二区 | 可以在线观看的av网站 | 日韩欧美一区二区三区免费观看 | 国产精品久久久久久久久久久小说 | jizzhd中国| 亚洲午夜视频在线观看 | 亚洲国产一区二区在线观看 | 日本久久久 | 国产精品久久a | 国产精品1区 | 中文字幕综合在线 | 久久久久久久国产精品 | 精品日韩一区 | 亚洲免费在线观看 |