iOS 面試要點

內存管理

軟件運行時會分配和使用設備的內存資源,因此,在軟件開發的過程中,需要進行內存管理,以保證高效、快速的分配內存,并且在適當的時候釋放和回收內存資源。其實,iOS的內存管理和其它操作系統大同小異,首先,iOS和其它系統一樣,內存分頁,每頁4K。多個頁構成一個region統一管理,負責管理的對象是VM object,其中包含了pager、size、resident pages等諸多屬性。

不管是Objective-C的[NSObject alloc],還是C代碼的對內存分配,最終重任都會落到malloc庫上,釋放也是如此,最終都將使用malloc庫中的free()。

一、Objective-C內存管理的對象

IOS開發中,內存中的對象主要有兩類,一類是值類型,如int、float、struct等基本數據類型,另一類是引用類型,也就是繼承自NSObject類的所有的OC對象。前一種值類型不需要我們管理,后一種引用類型是需要我們管理內存的,一旦管理不好,就會產生非常糟糕的后果。
為什么值類型不需要管理,而引用類型需要管理呢?那是因為他們分配內存方式不一樣。值類型會被放入棧中,他們依次緊密排列,在內存中占有一塊連續的內存空間,遵循先進后出的原則。引用類型會被放到堆中,當給對象分配內存空間時,會隨機的從內存當中開辟空間,對象與對象之間可能會留有不確定大小的空白空間,因此會產生很多內存碎片,需要我們管理。棧內存與堆內存從性能上比較,棧內存要優于堆內存,這是因為棧遵循先進后出的原則,因此當數據量過大時,存入棧會明顯的降低性能。因此,我們會把大量的數據存入堆中,然后棧中存放堆的地址,當需要調用數據時,就可以快速的通過棧內的地址找到堆中的數據。值類型和引用類型之間是可以相互轉化的,把值類型轉化為引用類型的過程叫做裝箱,比如把int包裝為NSNumber,這個過程會增加程序的運行時間,降低性能。而把引用類型轉為值類型的過程叫做拆箱,比如把NSNumer轉為float,在拆箱的過程中,我們一定要注意數據原有的類型,如果類型錯誤,可能導致拆箱失敗,因此會存在安全性的問題。手動的拆箱和裝箱,都會增加程序的運行時間,降低代碼可讀性,影響性能。在IOS開發過程中,棧內存中的值類型系統會自動管理,堆內存中的引用類型是需要我們管理的。每個OC對象內部都專門有四個字節來存儲引用計數器,它是一個整數,表示對象被引用的次數,通過它可以判斷對象是否被回收,如果引用計數為0,對象回收,不為0不回收。當對象執行alloc、new或者retain時,引用計數加1,release時,引用計數減1。

二、Objective-C管理內存的方式

Objective-c中提供了兩種內存管理機制MRC(Mannul Reference Counting)和ARC(Automatic Reference Counting),分別提供對內存的手動和自動管理,來滿足不同的需求。

1.MRC(人工引用計數),手動管理內存。

MRC模式下,所有的對象都需要手動的添加retain、release代碼來管理內存。使用MRC,需要遵守誰創建,誰回收的原則。也就是誰alloc,誰release;誰retain,誰release。當引用計數為0的時候,必須回收,引用計數不為0,不能回收,如果引用計數為0,但是沒有回收,會造成內存泄露。如果引用計數為0,繼續釋放,會造成野指針。為了避免出現野指針,我們在釋放的時候,會先讓指針=nil。

2.ARC(自動引用計數),自動管理內存。

ARC是IOS5推出的新功能,通過ARC,可以自動的管理內存。在ARC模式下,只要沒有強指針(強引用)指向對象,對象就會被釋放。在ARC模式下,不允許使用retain、release、retainCount等方法。并且,如果使用dealloc方法時,不允許調用[super dealloc]方法。ARC模式下的property變量修飾詞為strong、weak,相當于MRC模式下的retain、assign。strong :代替retain,缺省關鍵詞,代表強引用。weak:代替assign,聲明了一個可以自動設置nil的弱引用,但是比assign多一個功能,指針指向的地址被釋放之后,指針本身也會自動被釋放。

三、與內存有關的修飾符

strong :強引用,ARC中使用,與MRC中retain類似,使用之后,計數器+1。weak :弱引用 ,ARC中使用,如果只想的對象被釋放了,其指向nil,可以有效的避免野指針,其引用計數為1。readwrite : 可讀可寫特性,需要生成getter方法和setter方法時使用。readonly : 只讀特性,只會生成getter方法 不會生成setter方法,不希望屬性在類外改變。assign :賦值特性,不涉及引用計數,弱引用,setter方法將傳入參數賦值給實例變量,僅設置變量時使用。retain :表示持有特性,setter方法將傳入參數先保留,再賦值,傳入參數的retaincount會+1。copy :表示拷貝特性,setter方法將傳入對象復制一份,需要完全一份新的變量時。nonatomic :非原子操作,不加同步,多線程訪問可提高性能,但是線程不安全的。決定編譯器生成的setter getter是否是原子操作。atomic :原子操作,同步的,表示多線程安全,與nonatomic相反。

四、MRC與ARC混編

MRC與ARC理論上是不能兼容的,也就是你如果創建的項目是ARC模式的,在你的代碼中是不能使用release,否則會出現內存問題?,F在大部分程序都會選擇ARC的方式,但是很多第三方的框架是MRC模式,如果想把這些第三方的文件加到自己項目中,需要進行標識,否則編譯的時候會出現錯誤。在ARC的項目中,對MRC的文件可以添加編譯選項-fno-objc-arc的標識;在MRC的項目中,對ARC的文件可以添加編譯選項 -fobjc-arc的標識。


網絡

iOS中的多線程

*iOS中的多線程技術主要有NSThread, GCD和NSOperation。他們的封裝層次依次遞增,其中

  • NSThread封裝性最差,最偏向于底層,主要基于thread使用
  • GCD是基于C的API,直接使用比較方便,主要基于task使用
  • NSOperation是基于GCD封裝的NSObject對象,對于復雜的多線程項目使用比較方便,主要基于隊列使用.
    這篇文章主要介紹GCD中的queue相關知識。

微信公眾號

開發者思維 devthinking
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 序言 目前形勢,參加到iOS隊伍的人是越來越多,甚至已經到供過于求了。今年,找過工作人可能會更深刻地體會到今年的就...
    紅樓那一場夢閱讀 260評論 0 0
  • 1.OC的類可以多重繼承嗎?可以實現多個接口嗎?要想實現類似多重繼承如何實現?答:OC不可以實現多重繼承??梢詫崿F...
    歐辰_OSR閱讀 2,041評論 0 30
  • 久違的晴天,家長會。 家長大會開好到教室時,離放學已經沒多少時間了。班主任說已經安排了三個家長分享經驗。 放學鈴聲...
    飄雪兒5閱讀 7,574評論 16 22
  • 今天感恩節哎,感謝一直在我身邊的親朋好友。感恩相遇!感恩不離不棄。 中午開了第一次的黨會,身份的轉變要...
    迷月閃星情閱讀 10,615評論 0 11
  • 在妖界我有個名頭叫胡百曉,無論是何事,只要找到胡百曉即可有解決的辦法。因為是只狐貍大家以訛傳訛叫我“傾城百曉”,...
    貓九0110閱讀 3,348評論 7 3