自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

iOS經(jīng)典面試題總結(jié)--內(nèi)存管理

移動開發(fā)
我根據(jù)自己的情況做了一下總結(jié),答案是我總結(jié)的,如有答的不好的地方,希望批評指正以及交流,謝謝!

[[163414]]

我根據(jù)自己的情況做了一下總結(jié),答案是我總結(jié)的,如有答的不好的地方,希望批評指正以及交流,謝謝!

內(nèi)存管理

1.什么是ARC?

ARC是automatic reference counting自動引用計數(shù),在程序編譯時自動加入retain/release。在對象被創(chuàng)建時retain count+1,在對象被release時count-1,當(dāng)count=0時,銷毀對象。程序中加入autoreleasepool對象會由系統(tǒng)自動加上autorelease方法,如果該對象引用計數(shù)為0,則銷毀。那么ARC是為了解決MRC手動管理內(nèi)存存在的一些而誕生的。

MRC下內(nèi)存管理的缺點:

  • 釋放一個堆內(nèi)存時,首先要確定指向這個堆空間的指針都被release了。(避免提前釋放)
  • 釋放指針指向的堆空間,首先要確定哪些指向同一個堆,這些指針只能釋放一次。(避免釋放多次,造成內(nèi)存泄露)
  • 模塊化操作時,對象可能被多個模塊創(chuàng)建和使用,不能確定***由誰釋放
  • 多線程操作時,不確定哪個線程***使用完畢。

雖然ARC給我們編程帶來的很多好多,但也可能出現(xiàn)內(nèi)存泄露。如下面兩種情況:

  • 循環(huán)參照:A有個屬性參照B,B有個屬性參照A,如果都是strong參照的話,兩個對象都無法釋放。
  • 死循環(huán):如果有個ViewController中有***循環(huán),也會導(dǎo)致即使ViewController對應(yīng)的view消失了,ViewController也不能釋放。

2.block一般用那個關(guān)鍵字修飾,為什么?

block一般使用copy關(guān)鍵之進行修飾,block使用copy是從MRC遺留下來的“傳統(tǒng)”,在MRC中,方法內(nèi)容的block是在棧區(qū)的,使用copy可以把它放到堆區(qū)。但在ARC中寫不寫都行:編譯器自動對block進行了copy操作。

3.用@property聲明的NSString(或NSArray,NSDictionary)經(jīng)常使用copy關(guān)鍵字,為什么?如果改用strong關(guān)鍵字,可能造成什么問題?

答:用@property聲明 NSString、NSArray、NSDictionary 經(jīng)常使用copy關(guān)鍵字,是因為他們有對應(yīng)的可變類型:NSMutableString、NSMutableArray、NSMutableDictionary,他們之間可能進行賦值操作,為確保對象中的字符串值不會無意間變動,應(yīng)該在設(shè)置新屬性值時拷貝一份。

如果我們使用是strong,那么這個屬性就有可能指向一個可變對象,如果這個可變對象在外部被修改了,那么會影響該屬性。

copy此特質(zhì)所表達的所屬關(guān)系與strong類似。然而設(shè)置方法并不保留新值,而是將其“拷貝” (copy)。 當(dāng)屬性類型為NSString時,經(jīng)常用此特質(zhì)來保護其封裝性,因為傳遞給設(shè)置方法的新值有可能指向一個NSMutableString類的實例。這個類是NSString的子類,表示一種可修改其值的字符串,此時若是不拷貝字符串,那么設(shè)置完屬性之后,字符串的值就可能會在對象不知情的情況下遭人更改。所以,這時就要拷貝一份“不可變” (immutable)的字符串,確保對象中的字符串值不會無意間變動。只要實現(xiàn)屬性所用的對象是“可變的” (mutable),就應(yīng)該在設(shè)置新屬性值時拷貝一份。

4.runloop、autorelease pool以及線程之間的關(guān)系。

每個線程(包含主線程)都有一個Runloop。對于每一個Runloop,系統(tǒng)會隱式創(chuàng)建一個Autorelease pool,這樣所有的release pool會構(gòu)成一個像callstack一樣的一個棧式結(jié)構(gòu),在每一個Runloop結(jié)束時,當(dāng)前棧頂?shù)腁utorelease pool會被銷毀,這樣這個pool里的每個Object會被release。

5.@property 的本質(zhì)是什么?ivar、getter、setter 是如何生成并添加到這個類中的。

“屬性”(property)有兩大概念:ivar(實例變量)、存取方法(access method=getter),即@property = ivar + getter + setter。

例如下面的這個類:

  1. @interface WBTextView :UITextView   
  2. @property (nonatomic,copy)NSString *placehold;   
  3. @property (nonatomic,copy)UIColor *placeholdColor;   
  4. @end 

類完成屬性的定以后,編譯器會自動編寫訪問這些屬性的方法(自動合成autosynthesis),上述代碼寫出來的類等效與下面的代碼:

  1. @interface WBTextView :UITextView   
  2. - (NSString *)placehold;   
  3. -(void)setPlacehold:(NSString *)placehold;   
  4. -(UIColor *)placeholdColor;   
  5. -(void)setPlaceholdColor:(UIColor *)placeholdColor;   
  6. @end 

詳細介紹見:http://blog.csdn.net/jasonjwl/article/details/49427377

6.分別寫一個setter方法用于完成@property (nonatomic,retain)NSString *name和@property (nonatomic,copy) NSString *name

retain屬性的setter方法是保留新值并釋放舊值,然后更新實例變量,令其指向新值。順序很重要。假如還未保留新值就先把舊值釋放了,而且兩個值又指向同一個對象,先執(zhí)行的release操作就可能導(dǎo)致系統(tǒng)將此對象***回收。

  1. -(void)setName:(NSString *)name 
  2.     [name retain]; 
  3.     [_name release]; 
  4.     _name = name; 
  5. -(void)setName:(NSString *)name 
  6.       
  7.     [_name release]; 
  8.     _name = [name copy]; 

7.說說assign vs weak,_block vs _weak的區(qū)別

assign適用于基本數(shù)據(jù)類型,weak是適用于NSObject對象,并且是一個弱引用。

assign其實頁可以用來修飾對象,那么為什么不用它呢?因為被assign修飾的對象在釋放之后,指針的地址還是存在的,也就是說指針并沒有被置為nil。如果在后續(xù)內(nèi)存分配中,剛才分到了這塊地址,程序就會崩潰掉。而weak修飾的對象在釋放之后,指針地址會被置為nil。

_block是用來修飾一個變量,這個變量就可以在block中被修改。

_block:使用_block修飾的變量在block代碼塊中會被retain(ARC下,MRC下不會retain)

_weak:使用_weak修飾的變量不會在block代碼塊中被retain

8.請說出下面代碼是否有問題,如果有問題請修改?

  1. @autoreleasepool { 
  2.         for (int i=0; i[largeNumber; i++) { (因識別問題,該行代碼中尖括號改為方括號代替) 
  3.             Person *per = [[Person alloc] init]; 
  4.             [per autorelease]; 
  5.         } 
  6.     } 

內(nèi)存管理的原則:如果對一個對象使用了alloc、copy、retain,那么你必須使用相應(yīng)的release或者autorelease。咋一看,這道題目有alloc,也有autorelease,兩者對應(yīng)起來,應(yīng)該沒問題。但autorelease雖然會使引用計數(shù)減一,但是它并不是立即減一,它的本質(zhì)功能只是把對象放到離他最近的自動釋放池里。當(dāng)自動釋放池銷毀了,才會向自動釋放池中的每一個對象發(fā)送release消息。這道題的問題就在autorelease。因為largeNumber是一個很大的數(shù),autorelease又不能使引用計數(shù)立即減一,所以在循環(huán)結(jié)束前會造成內(nèi)存溢出的問題。

解決方案如下:

  1. @autoreleasepool { 
  2.         for (int i=0; i[100000; i++) { (因識別問題,該行代碼中尖括號改為方括號代替) 
  3.             @autoreleasepool { 
  4.             Person *per = [[Person alloc] init]; 
  5.             [per autorelease]; 
  6.         } 
  7.       } 
  8.     } 

在循環(huán)內(nèi)部再加一個自動釋放池,這樣就能保證每創(chuàng)建一個對象就能及時釋放。

9.請問下面代碼是否有問題,如有問題請修改?

  1. @autoreleasepool { 
  2.         NSString *str = [[NSString alloc] init]; 
  3.         [str retain]; 
  4.         [str retain]; 
  5.         str = @"jxl"
  6.         [str release]; 
  7.         [str release]; 
  8.         [str release]; 

這道題跟第8題一樣存在內(nèi)存泄露問題,1.內(nèi)存泄露 2.指向常量區(qū)的對象不能release。

指針變量str原本指向一塊開辟的堆區(qū)空間,但是經(jīng)過重新給str賦值,str的指向發(fā)生了變化,由原來指向堆區(qū)空間,到指向常量區(qū)。常量區(qū)的變量根本不需要釋放,這就導(dǎo)致了原來開辟的堆區(qū)空間沒有釋放,照成內(nèi)存泄露。

10.什么情況下使用weak關(guān)鍵字,相比assign有什么不同?什么情況使用weak關(guān)鍵字?

  • 在ARC中,在有可能出現(xiàn)循環(huán)引用的時候,往往要通過讓其中一端使用weak來解決。比如delegate代理
  • 自身已經(jīng)對它進行一次強引用,沒有必要再強引用一次,此時也會使用weak,自定義控件屬性一般也使用weak。

不同點:

  • weak此特質(zhì)表明該屬性定義了一種“非擁有關(guān)系”。為這種屬性設(shè)置新值時,設(shè)置方法既不保留新值,也不釋放舊值。此特性與assign一樣,然而在屬性所指的對象遭到推毀時,屬性值也會清空。而assign的“設(shè)置方法”只會執(zhí)行針對“純量類型” (scalar type,例如 CGFloat 或 NSlnteger 等)的簡單賦值操作。
  • assign可以用非OC對象,而weak必須用于OC對象。

11.內(nèi)存管理語義(assign、strong、weak等的區(qū)別)

  • assign “設(shè)置方法” 只會執(zhí)行針對“純量”的簡單賦值操作。
  • strong  此特質(zhì)表明該屬性定義了一種“擁有關(guān)系”。為這種屬性設(shè)置新值時,設(shè)置方法會先保留新值,并釋放舊值,然后再將新值設(shè)置上去。
  • weak 此特質(zhì)表明該屬性定義了一種“非擁有關(guān)系”。為這種屬性設(shè)置新值時,設(shè)置方法既不保留新值,也不釋放舊值。此特質(zhì)同assign類似,然而在屬性所指的對象遭到推毀時,屬性值也會清空。
  • unsafe_unretained  此特質(zhì)的語義和assign相同,但是它適用于“對象類型”,該特質(zhì)表達一種“非擁有關(guān)系”,當(dāng)目標對象遭到推毀時,屬性值不會自動清空,這一點與weak有區(qū)別。
  • copy 此特質(zhì)所表達的所屬關(guān)系與strong類似。然而設(shè)置方法并不保留新值,而是設(shè)置方法并不保留新值,而是將其“拷貝”。當(dāng)屬性類型為NSString*時,經(jīng)常用此特質(zhì)來保護其封裝性,因為傳遞給設(shè)置方法的新值有可能指向一個NSMutableString類的實例。這個類是NSString的子類,表示一種可以修改其值的字符串,此時若是不拷貝字符串,那么設(shè)置完屬性之后,字符串的值就可能會在對象不知情的情況下遭人更改。所以,這時就要拷貝一份“不可變”的字符串,確保對象中的字符串值不會無意間變動。只要實現(xiàn)屬性所用的對象是“可變的”,就應(yīng)該在設(shè)置新屬性值時拷貝一份。

后續(xù)會繼續(xù)增加內(nèi)存管理方面的內(nèi)容以及多線程等內(nèi)容,持續(xù)更新中....,敬請期待!

責(zé)任編輯:倪明 來源: CocoaChina
相關(guān)推薦

2024-04-15 08:34:43

2024-04-28 08:23:18

2014-07-28 14:00:40

linux面試題

2021-02-23 12:43:39

Redis面試題緩存

2021-12-01 09:25:58

SQL數(shù)據(jù)庫數(shù)據(jù)庫基礎(chǔ)

2024-07-24 08:38:07

2016-05-05 17:45:43

Spring面試題答案

2015-10-19 09:35:23

iOS面試

2024-04-01 08:34:23

2010-04-15 11:54:55

面試

2015-08-19 09:35:49

Java main面試題

2021-06-27 22:48:28

Redis數(shù)據(jù)庫內(nèi)存

2020-06-04 14:40:40

面試題Vue前端

2009-08-28 09:29:02

2023-11-13 07:37:36

JS面試題線程

2024-04-09 08:32:58

Java面試題線程

2011-03-24 13:27:37

SQL

2009-09-08 17:50:01

2024-04-07 08:23:49

Java面試題集合框架

2020-11-23 07:08:17

JVM逃逸元空間
點贊
收藏

51CTO技術(shù)棧公眾號