OC題目自答
1、請(qǐng)講講對(duì)像的本質(zhì)、內(nèi)存管理機(jī)制。
答:
內(nèi)存大?。?/i>
系統(tǒng)為NSObject對(duì)象分配了1
6個(gè)字節(jié)(通過(guò)malloc_size獲得的),但是NSObject對(duì)象內(nèi)部實(shí)際只使用了8個(gè)字節(jié)(通過(guò)class_getInstanceSize獲得的),這是isa占用的大小。
內(nèi)存對(duì)齊:
假設(shè)一個(gè)Person對(duì)象繼承自NSObject,有一個(gè)int屬性a,那么這個(gè)對(duì)象占16個(gè)字節(jié)。因?yàn)?+4 = 12,12<16 ,算作16個(gè),如果還有一個(gè)int b,那么剛好是16了。 如果還有一個(gè)int c呢? 這時(shí)候就變成32了。因?yàn)?8 + 4 *3 = 20,原本只占了20個(gè)字節(jié),但是需要遵循內(nèi)存對(duì)齊原則,所以是16翻倍, 結(jié)果變成32了。
對(duì)象種類(lèi)及isa指向:
OC對(duì)象分為3類(lèi):實(shí)例對(duì)象、類(lèi)對(duì)象、元類(lèi)對(duì)象。
實(shí)例對(duì)象的isa指向類(lèi)對(duì)象、類(lèi)對(duì)象的isa指向元類(lèi)對(duì)象、元類(lèi)對(duì)象的isa指向基元類(lèi)對(duì)象
OC類(lèi)信息存放的位置:
對(duì)象方法、屬性、成員變量、協(xié)議信息、存放在類(lèi)對(duì)象中。
類(lèi)方法,存放在元類(lèi)對(duì)象中
成員變量的具體值,存放在實(shí)例對(duì)象中。
為什么把對(duì)象的本質(zhì)與內(nèi)存管理機(jī)制放在一起?
因?yàn)閷?shí)例對(duì)象的isa中存放了與內(nèi)存管理緊密相關(guān)的東西:引用計(jì)數(shù)。
ARC中,OC對(duì)象在剛創(chuàng)建出來(lái)時(shí),引用計(jì)數(shù)就位1,當(dāng)被其他對(duì)象強(qiáng)引用時(shí),引用計(jì)數(shù)會(huì)加1,失去強(qiáng)引用則減1,當(dāng)引用計(jì)數(shù)為0的時(shí)候,對(duì)象則被銷(xiāo)毀。
isa指針占用了8個(gè)字節(jié),每個(gè)字節(jié)又有8個(gè)二進(jìn)制位,那么一共就占用了64個(gè)二進(jìn)制位。其中有19個(gè)二進(jìn)制位用來(lái)存放引用計(jì)數(shù),當(dāng)這19個(gè)二進(jìn)制位已經(jīng)不夠存下引用計(jì)數(shù)的時(shí)候,另一個(gè)二進(jìn)制位存放的bool會(huì)變成yes,此時(shí),系統(tǒng)會(huì)去另一個(gè)地方找引用計(jì)數(shù):sideTable。
既然提到內(nèi)存管理,也可以簡(jiǎn)單延伸聊幾句開(kāi)發(fā)中常遇到的內(nèi)存泄漏問(wèn)題,內(nèi)存泄漏一般是由循環(huán)強(qiáng)引用導(dǎo)致的,比如A強(qiáng)引用了B,B又強(qiáng)引用了A,這樣如果A想銷(xiāo)毀的話,需要等B先銷(xiāo)毀才行。B想銷(xiāo)毀呢,又需要A先銷(xiāo)毀。這樣你等我先,我等你先,就誰(shuí)都銷(xiāo)毀不了,這樣就出現(xiàn)了內(nèi)存泄漏。
如何打破這種僵局呢?只需將其中一根線變成虛線,也就是弱引用。比如A強(qiáng)引用了B,但是B弱引用A,這樣就不存在前面說(shuō)的僵局了。
或者使用NSProxy,插入第三者,比如A強(qiáng)引用B,B強(qiáng)引用Proxy,Proxy弱引用A,形成一個(gè)三角形。其實(shí)原理都差不多,都是需要一根弱引用的線,來(lái)打破僵局。
還有就是,為什么,使用masonry布局時(shí),在masonry的block內(nèi)部使用self,不會(huì)出現(xiàn)內(nèi)存泄漏?這個(gè)后面聊到block的時(shí)候,可以詳細(xì)講,包括為啥__weak 之后,就可以打破block循環(huán)循環(huán)也可以在后續(xù)詳細(xì)講。



在sideTable中 refcnts 其實(shí)就是引用計(jì)數(shù)。 weak_table 存放的是弱引用的計(jì)數(shù)。refcnts和weak_table都是散列表,使用對(duì)象的地址&上一個(gè)值,作為key,弱引用計(jì)數(shù)作為value。
OC中對(duì)象與swift中對(duì)象在內(nèi)存中的區(qū)別:
OC:前8個(gè)字節(jié)放isa指針,接著后面放存儲(chǔ)屬性,比如age = 18、height = 175、、、
Swift:前8個(gè)字節(jié)放MetaData數(shù)據(jù)(類(lèi)型信息),接著8個(gè)字節(jié)放引用計(jì)數(shù)(OC中的引用計(jì)數(shù)是通過(guò)isa指針去找的)。