1钩蚊、什么是ARC?
ARC全稱Automatic Reference Counting,是Objecive-C的內(nèi)存管理機(jī)制. 簡(jiǎn)單地來說,就是代碼中自動(dòng)加入了retain/release,原先需要手動(dòng)添加的用來處理內(nèi)存管理的引用計(jì)數(shù)代碼可以自動(dòng)地由編譯器完成了
ARC的使用是為了解決對(duì)象retain和release匹配的問題,以前手動(dòng)管理造成內(nèi)存泄漏或者重復(fù)解釋問題將不復(fù)存在
以前需要手動(dòng)的用過retain去為對(duì)象獲取內(nèi)存,并用release釋放內(nèi)存.所以以前的操作成為MRC(Manual Reference Counting).
ARC與Garbage collection的區(qū)別在于Garbage Collection 在runtime時(shí)管理內(nèi)存,可以解決retain cycle,而ARC在compile time 時(shí)管理內(nèi)存
2舔庶、請(qǐng)說明比較一下關(guān)鍵詞:strong, weak, assign, copy
strong 表示指向并擁有該對(duì)象,其修飾的對(duì)象引用計(jì)數(shù)會(huì)增加1.該對(duì)象只要引用計(jì)數(shù)不為0則不會(huì)被銷毀,當(dāng)然強(qiáng)行將其設(shè)為nil可以銷毀它
weak 表示指向但不擁有該對(duì)象,其修飾的對(duì)象引用計(jì)數(shù)不會(huì)增加.無需手動(dòng)設(shè)置,該對(duì)象會(huì)自行在內(nèi)存中銷毀.
assign 主要用于修飾基本數(shù)據(jù)類型,如NSInteger和CGFloat,這些數(shù)值主要存在于棧上
1). 修飾變量類型的區(qū)別
weak只可以修飾對(duì)象轮锥。如果修飾基本數(shù)據(jù)類型誓篱,編譯器會(huì)報(bào)錯(cuò)-“Property with ‘weak’ attribute must be of object type”圈浇。
assign可修飾對(duì)象果港,和基本數(shù)據(jù)類型胀屿。當(dāng)需要修飾對(duì)象類型時(shí),MRC時(shí)代使用unsafe_unretained酬核。當(dāng)然蜜另,unsafe_unretained也可能產(chǎn)生野指針,所以它名字是"unsafe_”嫡意。
2). 是否產(chǎn)生野指針的區(qū)別
weak不會(huì)產(chǎn)生野指針問題举瑰。因?yàn)閣eak修飾的對(duì)象釋放后(引用計(jì)數(shù)器值為0),指針會(huì)自動(dòng)被置nil蔬螟,之后再向該對(duì)象發(fā)消息也不會(huì)崩潰此迅。 weak是安全的。
assign如果修飾對(duì)象,會(huì)產(chǎn)生野指針問題耸序;如果修飾基本數(shù)據(jù)類型則是安全的忍些。修飾的對(duì)象釋放后,指針不會(huì)自動(dòng)被置空坎怪,此時(shí)向?qū)ο蟀l(fā)消息會(huì)崩潰罢坝。
weak 一般用來修飾對(duì)象,assign一般用來修飾基本數(shù)據(jù)類型.原因是assign修飾的對(duì)象被釋放后,指針的地址依然存在,造成野指針,在堆上容易造成崩潰,而沾上的內(nèi)存系統(tǒng)會(huì)自動(dòng)處理,不會(huì)造成野指針
copy與strong類似,不同之處是strong的復(fù)制是多個(gè)指針指向同一個(gè)地址,而copy的復(fù)制每次會(huì)在內(nèi)存中拷貝一份對(duì)象,指針指向不同的地址.copy一般用于修飾有可變對(duì)應(yīng)類型的不可變對(duì)象上,如NSString,NSArray,NSDictionary
Objective-C中,基本數(shù)據(jù)類型的默認(rèn)關(guān)鍵字是atomic, readwrite, assign ; 普通屬性的默認(rèn)關(guān)鍵字atomic, readwrite, strong]
3、weak指針自動(dòng)被置為nil的實(shí)現(xiàn)原理
Runtime維護(hù)了一個(gè)weak表,用于存儲(chǔ)指向某個(gè)對(duì)象的多有weak指針,weak表其實(shí)就是一個(gè)哈希表,Key是所指對(duì)象的地址,Value是weak指針的地址(這個(gè)地址的值是所指對(duì)象的地址)數(shù)組.
具體步驟:
1). 初始化時(shí):runtime會(huì)調(diào)用objc_initWeak函數(shù),初始化一個(gè)新的weak指針指向?qū)ο蟮刂?br>
2). 添加引用時(shí):objc_initWeak函數(shù)會(huì)調(diào)用objc_storeWeak()的作用是更新指針指向,創(chuàng)建對(duì)應(yīng)的弱引用表
3). 釋放時(shí),調(diào)用clearDeallocating函數(shù),clearDeallocation函數(shù)首先根據(jù)對(duì)象地址獲取所有weak指針地址數(shù)組,然后遍歷這個(gè)數(shù)組把其中的數(shù)據(jù)設(shè)置為nil,最后把這個(gè)entry從weak表中刪除,最后清理對(duì)象記錄
當(dāng)weak引用指向的對(duì)象被釋放時(shí),如何去處理weak指針?
1 >調(diào)用objc_release
2> 因?yàn)閷?duì)象的引用計(jì)數(shù)為0, 所以執(zhí)行dealloc
3>在dealloc中,調(diào)用_objc_rootDealloc函數(shù)
4> 在_objc_rootDealloc中,調(diào)用了object_dispose函數(shù)
5 >調(diào)用objc_destructInstance
6> 最后調(diào)用objc_clear_deallocating
簡(jiǎn)單來說
a 從weak表中獲取被釋放對(duì)象的地址為鍵值的記錄
b. 將包含在記錄中的所有附有weak修飾符變量的地址,賦值為nil
c. 將weak表中該記錄刪除
d. 從引用計(jì)數(shù)表中刪除廢棄對(duì)象的地址為鍵值的記錄
請(qǐng)說明比較一下關(guān)鍵詞: atomic, nonatomic
atomic 修飾的對(duì)象會(huì)保證setter和getter的完整性,任何線程對(duì)其訪問都可以得到一個(gè)完整的初始化后的對(duì)象,因?yàn)橐WC操作完成,所以速度慢.它比nonatomic安全,但也并不是絕對(duì)線程安全,例如多個(gè)線程同時(shí)調(diào)用set和get就會(huì)導(dǎo)致獲取的對(duì)象值不一樣.絕對(duì)安全的線程就要用@synchronized
nonatomic 修飾的對(duì)象不保證setter和getter的完整性,所以多個(gè)線程對(duì)他進(jìn)行訪問,它可能會(huì)返回未初始化的對(duì)象,正因?yàn)槿绱?它比atomic快,但也是線程不安全的
4搅窿、runloop和線程有什么關(guān)系?
runloop是每一個(gè)線程一直運(yùn)行的一個(gè)對(duì)象,它主要用來負(fù)責(zé)相應(yīng)需要處理的各種事件和消息.每一個(gè)線程都有且僅有一個(gè)runloop與其對(duì)應(yīng),沒有線程,就沒有runloop
其中所有線程中,只有主線程的runloop是默認(rèn)開啟的,main函數(shù)會(huì)設(shè)置一個(gè)NSRunloop對(duì)象,其他線程,runloop默認(rèn)是沒有啟動(dòng)的,我們可以通過 [NSRunloop currentRunloop]來獲取
5嘁酿、請(qǐng)說明比較一下關(guān)鍵詞: __weak, __block
__weak 與 weak基本相同,前者用于修飾變量(variable),后者用于修飾屬性(property).__weak主要用于方式block中的循環(huán)引用.
__block也用于修飾變量。它是引用修飾,所以其修飾的值是動(dòng)態(tài)變化的,即可以被重新賦值的男应。__block用于修飾某些block內(nèi)部將要修飾的外部變量闹司。
__weak和__block的使用場(chǎng)景幾句與block息息相關(guān)。而所謂block就是Objective-C對(duì)于閉包的實(shí)現(xiàn),閉包就是名字的函數(shù),或者理解為指向函數(shù)的指針
6沐飘、分類和擴(kuò)展有什么區(qū)別游桩?可以分別用來做什么?分類有哪些局限性耐朴?分類的結(jié)構(gòu)體里面有哪些成員借卧?
原文 : http://www.reibang.com/p/9e827a1708c6
區(qū)別: 1)、分類原則上只能增加方法(能添加屬性的原因只是因?yàn)橥ㄟ^runtime決絕無setter/getter的問題)
2)隔箍、類擴(kuò)展不僅可以添加方法,還可以添加實(shí)例變量(屬性),只是該實(shí)例變量默認(rèn)是@private類型的(用范圍只能在自身類,而不是子類或其他地方)
3)谓娃、類擴(kuò)展中聲明的方法沒被實(shí)現(xiàn),編譯器會(huì)報(bào)警,但是類別中的方法沒被實(shí)現(xiàn)編譯器是不會(huì)有任何警告的。這是因?yàn)轭悢U(kuò)展是在編譯階段被添加到類中的,而分類是在運(yùn)行時(shí)添加到類中的
4)蜒滩、類擴(kuò)展不能想分類那樣擁有獨(dú)立的實(shí)現(xiàn)部分(@implementation部分),也就是說,類擴(kuò)展所聲明的方法必須依托對(duì)應(yīng)類型的實(shí)現(xiàn)部分來實(shí)現(xiàn)
5)滨达、定義在.m文件中的類擴(kuò)展方法為私有的,定義在.h文件中(頭文件)中的類擴(kuò)展方法是公有的。類擴(kuò)展是在.m中聲明私有方法的最好的方式
作用:
分類在不修改原有的類的基礎(chǔ)上俯艰,為一個(gè)類擴(kuò)展方法,最主要的可以給系統(tǒng)類擴(kuò)張我們自己定義的方法
類擴(kuò)展為一個(gè)類添加原來沒有的變量,方法和屬性,一般寫在.m文件中
1):category的主要作用是為已經(jīng)存在的類添加方法
下面也有其他作用可以了解下:
2):可以把類的實(shí)現(xiàn)分開在幾個(gè)不同的文件里面,
(可以減少單個(gè)文件的體積
可以把不同的功能組織到不同的category里
可以由多個(gè)開發(fā)者共同完成一個(gè)類
可以按需加載想要的category)
3):模擬多繼承
4):把framework的私有方法公開
擴(kuò)展的作用:為一個(gè)類添加額外的原來沒有變量捡遍,方法和屬性
分類局限性:
1)、無法向類中添加新的實(shí)例變量
2)竹握、名稱沖突,即當(dāng)類別中的方法與原始類方法名稱沖突時(shí),類別具有更高的優(yōu)先級(jí)
3)画株、如果多個(gè)分類中都有和原有類中同名的方法,那么調(diào)用該方法的時(shí)候執(zhí)行誰由該編譯器決定;編譯器會(huì)執(zhí)行最后一個(gè)參與編譯的分類中的方法
7、sclassof 和 isCLassMemberof 的區(qū)別?
相同點(diǎn): 都是NSObject的比較Class的方法.
不同點(diǎn): isKindOfClass:確定一個(gè)對(duì)象是否是一個(gè)類的成員,或者是派生自該類的成員.
isMemberOfClass:確定一個(gè)對(duì)象是否是當(dāng)前類的成員.