iOS面試及答案_第1頁
iOS面試及答案_第2頁
iOS面試及答案_第3頁
iOS面試及答案_第4頁
iOS面試及答案_第5頁
已閱讀5頁,還剩48頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、史上最全的iOS面試題及答案  iOS面試小貼士回答好下面的足夠了-多線程、特別是NSOperation 和 GCD 的內(nèi)部原理。運行時機制的原理和運用場景。SDWebImage的原理。實現(xiàn)機制。如何解決TableView卡的問題。block和代理的,通知的區(qū)別。block的用法需要注意些什么。strong,weak,retain,assign,copy nomatic 等的區(qū)別。設(shè)計模式,mvc,單利,工廠,代理等的應(yīng)用場景。單利的寫法。在單利中創(chuàng)建數(shù)組應(yīng)該注意些什么。NSString 的時候用copy和strong的區(qū)別。響應(yīng)值鏈。NSTimer 在子線程中應(yīng)該手動創(chuàng)建

2、NSRunLoop ,否則不能循環(huán)執(zhí)行。UIScrollView和NSTimer組合做循環(huán)廣告圖輪播的時候有一個屬性可以控制當(dāng)上下滾動tableview的時候廣告輪播圖依然正常滾動。Xcode最新的自動布局。這個很多公司都用。盡量自學(xué)下。git ,和svn的用法。git的幾個命令簡單的記下。友盟報錯可以查到具體某一行的錯誤,原理是什么。Instrument  可以檢測 電池的耗電量、和內(nèi)存的消耗。的用法。動畫CABaseAnimation CAKeyAni.  CATrans.  CAGoup.    等熟悉。ARC的原理。自己寫過什么自定義控

3、件就最好了。 回答好上面的足夠了- _block和_weak修飾符的區(qū)別其實是挺明顯的: 1._block不管是ARC還是MRC模式下都可以使用,可以修飾對象,還可以修飾基本數(shù)據(jù)類型。 2._weak只能在ARC模式下使用,也只能修飾對象(NSString),不能修飾基本數(shù)據(jù)類型(int)。 3._block對象可以在block中被重新賦值,_weak不可以。   tableView 滑動卡的問題主要是因為:從緩存中或者是從本地讀取圖片給UIImage的時候耗費的時間。需要把下面的兩句話放到子線程里面:1. NSD

4、ata *imgData = NSData dataWithContentsOfURL:NSURL URLWithString:app.icon; /得到圖像數(shù)據(jù)  2.         UIImage *image = UIImage imageWithData:imgData;   把UIImage賦值給圖片的時候在主線程。子線程不能更新UI 所有的UI跟新都是主線程執(zhí)行了

5、。手指滑動屏幕了?;蛘咂聊坏哪硞€方法執(zhí)行了。 子線程里面加入NSTimer 的時候需要 手動添加NSRunloop   否則不能循環(huán)。 單利里面添加 NSMutableArray 的時候,防止多個地方對它同時便利和修改的話,需要加原子屬性。并且用strong,并且寫一個遍歷和修改的方法。加上鎖。   Lock   UnLock         _weak ViewController*  weakSelf = self;GCD里面用 _weak 防止內(nèi)存釋放不了,循環(huán)引用。 

6、   二、SDWebImage內(nèi)部實現(xiàn)過程1. 入口 setImageWithURL:placeholderImage:options: 會先把 placeholderImage 顯示,然后 SDWebImageManager 根據(jù) URL 開始處理圖片。2. 進入 SDWebImageManager-downloadWithURL:delegate:options:userInfo:,交給 SDImageCache 從緩存查找圖片是否已經(jīng)下載 queryDiskCacheForKey:delegate:userInfo:.3. 先從內(nèi)存圖片緩存查找是否有圖片,如

7、果內(nèi)存中已經(jīng)有圖片緩存,SDImageCacheDelegate 回調(diào) imageCache:didFindImage:forKey:userInfo: 到 SDWebImageManager。4. SDWebImageManagerDelegate 回調(diào) webImageManager:didFinishWithImage: 到 UIImageView+WebCache 等前端展示圖片。5. 如果內(nèi)存緩存中沒有,生成 NSInvocationOperation 添加到隊列開始從硬盤查找圖片是否已經(jīng)緩存。6. 根據(jù) URLKey 在硬盤緩存目錄下嘗試讀取圖片文件。這一步是在 NSOperati

8、on 進行的操作,所以回主線程進行結(jié)果回調(diào) notifyDelegate:。7. 如果上一操作從硬盤讀取到了圖片,將圖片添加到內(nèi)存緩存中(如果空閑內(nèi)存過小,會先清空內(nèi)存緩存)。SDImageCacheDelegate 回調(diào) imageCache:didFindImage:forKey:userInfo:。進而回調(diào)展示圖片。8. 如果從硬盤緩存目錄讀取不到圖片,說明所有緩存都不存在該圖片,需要下載圖片,回調(diào) imageCache:didNotFindImageForKey:userInfo:。9. 共享或重新生成一個下載器 SDWebImageDownloader 開始下載圖片。10. 圖片下載

9、由 NSURLConnection 來做,實現(xiàn)相關(guān) delegate 來判斷圖片下載中、下載完成和下載失敗。11. connection:didReceiveData: 中利用 ImageIO 做了按圖片下載進度加載效果。12. connectionDidFinishLoading: 數(shù)據(jù)下載完成后交給 SDWebImageDecoder 做圖片解碼處理。13. 圖片解碼處理在一個 NSOperationQueue 完成,不會拖慢主線程 UI。如果有需要對下載的圖片進行二次處理,最好也在這里完成,效率會好很多。14. 在主線程 notifyDelegateOnMainThreadWithInf

10、o: 宣告解碼完成,imageDecoder:didFinishDecodingImage:userInfo: 回調(diào)給 SDWebImageDownloader。15. imageDownloader:didFinishWithImage: 回調(diào)給 SDWebImageManager 告知圖片下載完成。16. 通知所有的 downloadDelegates 下載完成,回調(diào)給需要的地方展示圖片。17. 將圖片保存到 SDImageCache 中,內(nèi)存緩存和硬盤緩存同時保存。寫文件到硬盤也在以單獨 NSInvocationOperation 完成,避免拖慢主線程。18. SDImageCache

11、在初始化的時候會注冊一些消息通知,在內(nèi)存警告或退到后臺的時候清理內(nèi)存圖片緩存,應(yīng)用結(jié)束的時候清理過期圖片。19. SDWI 也提供了 UIButton+WebCache 和 MKAnnotationView+WebCache,方便使用。20. SDWebImagePrefetcher 可以預(yù)先下載圖片,方便后續(xù)使用。從上面流程可以看出,當(dāng)你調(diào)用setImageWithURL:方法的時候,他會自動去給你干這么多事,當(dāng)你需要在某一具體時刻做事情的時候,你可以覆蓋這些方法。比如在下載某個圖片的過程中要響應(yīng)一個事件,就覆蓋這個方法:1234567891011/覆蓋方法,指哪打哪,這個方法是下載imag

12、ePath2的時候響應(yīng)    SDWebImageManager *manager = SDWebImageManager sharedManager;          manager downloadImageWithURL:imagePath2 options:SDWebImageRetryFailed progress:(NSInteger receivedSize, 

13、NSInteger expectedSize)                   NSLog("顯示當(dāng)前進度");               completed:(UIImage *image, NSError *e

14、rror, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL)                   NSLog("下載完成");      對于初級來說,用sd_setImageWithURL:的若干個方法就可以實現(xiàn)很好的圖片緩存。

15、 UIButton 的父類是UIControl  UIControl的父類是UIView UIView的父類是 UIResponder http狀態(tài)嗎 :302 是請求重定向。500以上是服務(wù)器錯誤。400以上是請求鏈接錯誤或者找不到服務(wù)器。200以上是正確。100以上是請求接受成功。  HTTP Keep-Alive詳解轉(zhuǎn)HTTP是一個請求<->響應(yīng)模式的典型范例,即客戶端向服務(wù)器發(fā)送一個請求信息,服務(wù)器來響應(yīng)這個信息。在老的HTTP版本中,每個請求都將被創(chuàng)建一個新的客戶端->服務(wù)器的連接,在這個連接上發(fā)送請求,然后接收請求

16、。這樣的模式有一個很大的優(yōu)點就是,它很簡單,很容易理解和編程實現(xiàn);它也有一個很大的缺點就是,它效率很低,因此Keep-Alive被提出用來解決效率低的問題。Keep-Alive功能使客戶端到服務(wù)器端的連接持續(xù)有效,當(dāng)出現(xiàn)對服務(wù)器的后繼請求時,Keep-Alive功能避免了建立或者重新建立連接。市場上 的大部分Web服務(wù)器,包括iPlanet、IIS和Apache,都支持HTTP Keep-Alive。對于提供靜態(tài)內(nèi)容的網(wǎng)站來說,這個功能通常很有用。但是,對于負擔(dān)較重的網(wǎng)站來說,這里存在另外一個問題:雖然為客戶保留打開的連 接有一定的好處,但它同樣影響了性能,因為在處理暫停期間,本來可

17、以釋放的資源仍舊被占用。當(dāng)Web服務(wù)器和應(yīng)用服務(wù)器在同一臺機器上運行時,Keep- Alive功能對資源利用的影響尤其突出。 此功能為HTTP 1.1預(yù)設(shè)的功能,HTTP 1.0加上Keep-Aliveheader也可以提供HTTP的持續(xù)作用功能。Keep-Alive: timeout=5, max=100timeout:過期時間5秒(對應(yīng)httpd.conf里的參數(shù)是:KeepAliveTimeout),max是最多一百次請求,強制斷掉連接就是在timeout時間內(nèi)又有新的連接過來,同時max會自動減1,直到為0,強制斷掉。見下面的四個圖,注意看Date的值(前后時間差都是在5秒之

18、內(nèi))!HTTP/1.0在HTTP/1.0版本中,并沒有官方的標(biāo)準來規(guī)定Keep-Alive如何工作,因此實際上它是被附加到HTTP/1.0協(xié)議上,如果客戶端瀏覽器支持Keep-Alive,那么就在HTTP請求頭中添加一個字段 Connection: Keep-Alive,當(dāng)服務(wù)器收到附帶有Connection: Keep-Alive的請求時,它也會在響應(yīng)頭中添加一個同樣的字段來使用Keep-Alive。這樣一來,客戶端和服務(wù)器之間的HTTP連接就會被保持,不會斷開(超過Keep-Alive規(guī)定的時間,意外斷電等情況除外),當(dāng)客戶端發(fā)送另外一個請求時,就使用這條已經(jīng)建立的連接HTTP/

19、1.1在HTTP/1.1版本中,官方規(guī)定的Keep-Alive使用標(biāo)準和在HTTP/1.0版本中有些不同,默認情況下所在HTTP1.1中所有連接都被保持,除非在請求頭或響應(yīng)頭中指明要關(guān)閉:Connection: Close  ,這也就是為什么Connection: Keep-Alive字段再沒有意義的原因。另外,還添加了一個新的字段Keep-Alive:,因為這個字段并沒有詳細描述用來做什么,可忽略它Not reliable(不可靠)HTTP是一個無狀態(tài)協(xié)議,這意味著每個請求都是獨立的,Keep-Alive沒能改變這個結(jié)果。另外,Keep-Alive也不能保證客戶端和服務(wù)器之間的連接

20、一定是活躍的,在HTTP1.1版本中也如此。唯一能保證的就是當(dāng)連接被關(guān)閉時你能得到一個通知,所以不應(yīng)該讓程序依賴于Keep-Alive的保持連接特性,否則會有意想不到的后果Keep-Alive和POST在HTTP1.1細則中規(guī)定了在一個POST消息體后面不能有任何字符,還指出了對于某一個特定的瀏覽器可能并不遵循這個標(biāo)準(比如在POST消息體的后面放置一個CRLF符)。而據(jù)我所知,大部分瀏覽器在POST消息體后都會自動跟一個CRLF符再發(fā)送,如何解決這個問題呢?根據(jù)上面的說明在POST請求頭中禁止使用Keep-Alive,或者由服務(wù)器自動忽略這個CRLF,大部分服務(wù)器都會自動忽略,但是在未經(jīng)測試

21、之前是不可能知道一個服務(wù)器是否會這樣做。 1、常用的方法dispatch_async為了避免界面在處理耗時的操作時卡死,比如讀取網(wǎng)絡(luò)數(shù)據(jù),IO,數(shù)據(jù)庫讀寫等,我們會在另外一個線程中處理這些操作,然后通知主線程更新界面。用GCD實現(xiàn)這個流程的操作比前面介紹的NSThread  NSOperation的方法都要簡單。代碼框架結(jié)構(gòu)如下: 1. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),   2.   

22、  / 耗時的操作  3.     dispatch_async(dispatch_get_main_queue(),   4.         / 更新界面  5.     );  6. );  如果這樣還不清晰的話,那我們還是用上兩篇博客中的下載圖片為例子,代碼如下: 

23、60;1. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),   2.     NSURL * url = NSURL URLWithString:"3.     NSData * data = NSData allocinitWithContentsOfURL:

24、url;  4.     UIImage *image = UIImage allocinitWithData:data;  5.     if (data != nil)   6.         dispatch_async(dispatch_get_main_queue(), 

25、60; 7.             self.imageView.image = image;  8.          );  9.       10. );   運行顯示:是不是代碼比NSThread  NSOpe

26、ration簡潔很多,而且GCD會自動根據(jù)任務(wù)在多核處理器上分配資源,優(yōu)化程序。系統(tǒng)給每一個應(yīng)用程序提供了三個concurrent dispatch queues。這三個并發(fā)調(diào)度隊列是全局的,它們只有優(yōu)先級的不同。因為是全局的,我們不需要去創(chuàng)建。我們只需要通過使用函數(shù)dispath_get_global_queue去得到隊列,如下: 1. dispatch_queue_t globalQ = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);  

27、60;  這里也用到了系統(tǒng)默認就有一個串行隊列main_queue 1. dispatch_queue_t mainQ = dispatch_get_main_queue();     雖然dispatch queue是引用計數(shù)的對象,但是以上兩個都是全局的隊列,不用retain或release。2、dispatch_group_async的使用dispatch_group_async可以實現(xiàn)監(jiān)聽一組任務(wù)是否完成,完成后得到通知執(zhí)行其他的操作。這個方法很有用,比如你執(zhí)行三個下載任務(wù),當(dāng)

28、三個任務(wù)都下載完成后你才通知界面說完成的了。下面是一段例子代碼: 1. dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);  2. dispatch_group_t group = dispatch_group_create();  3. dispatch_group_async(group, queue,   4

29、.     NSThread sleepForTimeInterval:1;  5.     NSLog("group1");  6. );  7. dispatch_group_async(group, queue,   8.     NSThread sleepForTimeInterval:2;  9. 

30、0;   NSLog("group2");  10. );  11. dispatch_group_async(group, queue,   12.     NSThread sleepForTimeInterval:3;  13.     NSLog("group3");  14. );  15

31、. dispatch_group_notify(group, dispatch_get_main_queue(),   16.     NSLog("updateUi");  17. );  18. dispatch_release(group);  dispatch_group_async是異步的方法,運行后可以看到打印結(jié)果: 2012-09-25 16:04:16.737 gcdTest43328:11303 group1

32、2012-09-25 16:04:17.738 gcdTest43328:12a1b group22012-09-25 16:04:18.738 gcdTest43328:13003 group32012-09-25 16:04:18.739 gcdTest43328:f803 updateUi每個一秒打印一個,當(dāng)?shù)谌齻€任務(wù)執(zhí)行后,upadteUi被打印。 3、dispatch_barrier_async的使用dispatch_barrier_async是在前面的任務(wù)執(zhí)行結(jié)束后它才執(zhí)行,而且它后面的任務(wù)等它執(zhí)行完成之后才會執(zhí)行例子代碼如下: 1. dispatch_queu

33、e_t queue = dispatch_queue_create("gcdtest.rongfzh.yc", DISPATCH_QUEUE_CONCURRENT);  2. dispatch_async(queue,   3.     NSThread sleepForTimeInterval:2;  4.     NSLog("dispatch_async1&qu

34、ot;);  5. );  6. dispatch_async(queue,   7.     NSThread sleepForTimeInterval:4;  8.     NSLog("dispatch_async2");  9. );  10. dispatch_barrier_async(queue,   11. &#

35、160;   NSLog("dispatch_barrier_async");  12.     NSThread sleepForTimeInterval:4;  13.   14. );  15. dispatch_async(queue,   16.     NSThread sleepForTimeInterval:1; 

36、; 17.     NSLog("dispatch_async3");  18. );  打印結(jié)果: 2012-09-25 16:20:33.967 gcdTest45547:11203 dispatch_async12012-09-25 16:20:35.967 gcdTest45547:11303 dispatch_async22012-09-25 16:20:35.967 gcdTest45547:11303 dispatch_barrier_async2012-09-

37、25 16:20:40.970 gcdTest45547:11303 dispatch_async3請注意執(zhí)行的時間,可以看到執(zhí)行的順序如上所述。4、dispatch_apply 執(zhí)行某個代碼片段N次。dispatch_apply(5, globalQ, (size_t index)     / 執(zhí)行5次);  copy與retain:1、copy其實是建立了一個相同的對象,而retain不是;2、copy是內(nèi)容拷貝,retain是指針拷貝;  3、copy是內(nèi)容的拷貝 ,對于像NSString,的確是這樣,但是如果copy

38、的是一個NSArray呢?這時只是copy了指向array中相對應(yīng)元素的指針.這便是所謂的"淺復(fù)制".4、copy的情況:NSString *newPt = pt copy;此時會在堆上重新開辟一段內(nèi)存存放"abc" 比如0X1122 內(nèi)容為"abc 同時會在棧上為newPt分配空間 比如地址:0Xaacc 內(nèi)容為0X1122 因此retainCount增加1供newPt來管理0X1122這段內(nèi)存;assign與retain:1、assign: 簡單賦值,不更改索引計數(shù);2、assign的情況:NSString *newPt = pt assi

39、ng; 此時newPt和pt完全相同 地址都是0Xaaaa 內(nèi)容為0X1111 即newPt只是pt的別名,對任何一個操作就等于對另一個操作, 因此retainCount不需要增加;3、assign就是直接賦值;4、retain使用了引用計數(shù),retain引起引用計數(shù)加1, release引起引用計數(shù)減1,當(dāng)引用計數(shù)為0時,dealloc函數(shù)被調(diào)用,內(nèi)存被回收;    5、retain的情況:NSString *newPt = pt retain; 此時newPt的地址不再為0Xaaaa,可能為0Xaabb 但是內(nèi)容依然為0X1111

40、。 因此newPt 和 pt 都可以管理"abc"所在的內(nèi)存,因此 retainCount需要增加1 ;readonly:1、屬性是只讀的,默認的標(biāo)記是讀寫,如果你指定了只讀,在implementation中只需要一個讀取器?;蛘呷绻闶褂胹ynthesize關(guān)鍵字,也是有讀取器方法被解析  readwrite:1、說明屬性會被當(dāng)成讀寫的,這也是默認屬性。設(shè)置器和讀取器都需要在implementation中實現(xiàn)。如果使用synthesize關(guān)鍵字,讀取器和設(shè)置器都會被解析;nonatomic:1、非原子性訪問,對屬性賦值的時候不加鎖,多線程并發(fā)

41、訪問會提高性能。如果不加此屬性,則默認是兩個訪問方法都為原子型事務(wù)訪問;weak and strong property (強引用和弱引用的區(qū)別):1、 weak 和 strong 屬性只有在你打開ARC時才會被要求使用,這時你是不能使用retain release autorelease 操作的,因為ARC會自動為你做好這些操作,但是你需要在對象屬性上使用weak 和strong,其中strong就相當(dāng)于retain屬性,而weak相當(dāng)于assign。2、只有一種情況你需要使用weak(默認是strong),就是為了避免retain cycles(就是父類中含有子類父類retain

42、了子類,子類中又調(diào)用了父類子類又retain了父類,這樣都無法release)    3、聲明為weak的指針,指針指向的地址一旦被釋放,這些指針都將被賦值為nil。這樣的好處能有效的防止野指針。    ARC(Automatic Reference Counting):1、就是代碼中自動加入了retain/release,原先需要手動添加的用來處理內(nèi)存管理的引用計數(shù)的代碼可以自動地由編譯器完成了。該機能在 iOS 5/ Mac OS X 10.7 開始導(dǎo)入,利用 Xcode4.2 以后可以使用該特性。strong

43、,weak,copy 具體用法:1.具體一點:IBOutlet可以為weak,NSString為copy,Delegate一般為weak,其他的看情況。一般來說,類“內(nèi)部”的屬性設(shè)置為strong,類“外部”的屬性設(shè)置為weak。說到底就是一個歸屬權(quán)的問題。小心出現(xiàn)循環(huán)引用導(dǎo)致內(nèi)存無法釋放。2.不用ARC的話就會看到很多retian。3.如果你寫了synthesize abc = _abc;的話,系統(tǒng)自動幫你聲明了一個_abc的實例變量。   使用assign: 對基礎(chǔ)數(shù)據(jù)類型 (NSInteger)和C數(shù)據(jù)類型(int, float, double, char,等)

44、60;  使用copy: 對NSString    使用retain: 對其他NSObject和其子類   1. 1.寫一個NSString類的實現(xiàn)+ (id)initWithCString:(c*t char *)nullTerminatedCString encoding:(NSStringEncoding)encoding; + (id) stringWithCString: (c*t char*)nullTerminatedCString     

45、         encoding: (NSStringEncoding)encoding    NSString  *obj;   obj = self allocWithZone: NSDefaultMallocZone();   obj = obj initWithCString: nullTerminatedCString encoding: encoding;   return AUTORELEASE(ob

46、j);  2static 關(guān)鍵字的作用: (1)函數(shù)體內(nèi) static 變量的作用范圍為該函數(shù)體,不同于 auto 變量,該變量的內(nèi)存只被分配一次, 因此其值在下次調(diào)用時仍維持上次的值; (2)在模塊內(nèi)的 static 全局變量可以被模塊內(nèi)所用函數(shù)訪問,但不能被模塊外其它函數(shù)訪問; (3)在模塊內(nèi)的 static 函數(shù)只可被這一模塊內(nèi)的其它函數(shù)調(diào)用,這個函數(shù)的使用范圍被限制在聲明 它的模塊內(nèi); (4)在類中的 sta

47、tic 成員變量屬于整個類所擁有,對類的所有對象只有一份拷貝; (5)在類中的 static 成員函數(shù)屬于整個類所擁有,這個函數(shù)不接收 this 指針,因而只能訪問類的static 成員變量。  3線程與進程的區(qū)別和聯(lián)系? 進程和線程都是由操作系統(tǒng)所體會的程序運行的基本單元,系統(tǒng)利用該基本單元實現(xiàn)系統(tǒng)對應(yīng)用的并發(fā)性。 程和線程的主要差別在于它們是不同的操作系統(tǒng)資源管理方式。進程有獨立的地址空間,一個進程崩潰后,在保護模式下不會對其它進程產(chǎn)生影響,而線程只是一個進程中的不同執(zhí)行路徑。線程

48、有自己的堆棧和局部變量,但線程之間沒有單獨的地址空間,一個線程死掉就等于整個進程死掉,所以多進程的程序要比多線程的程序健壯,但在進程切換時,耗費資源較大,效率要差一些。但對于一些要求同時進行并且又要共享某些變量的并發(fā)操作,只能用線程,不能用進程。4堆和棧的區(qū)別 管理方式:對于棧來講,是由編譯器自動管理,無需我們手工控制;對于堆來說,釋放工作由程序員控制,容易產(chǎn)生memory leak。 申請大?。?#160;棧:在Windows下,棧是向低地址擴展的數(shù)據(jù)結(jié)構(gòu),是一塊連續(xù)的內(nèi)存的區(qū)域。這句話的意思是棧頂?shù)牡刂泛蜅5淖畲笕萘渴窍到y(tǒng)預(yù)先規(guī)定好的,在 WINDOWS下,棧

49、的大小是2M(也有的說是1M,總之是一個編譯時就確定的常數(shù)),如果申請的空間超過棧的剩余空間時,將提示overflow。因此,能從棧獲得的空間較小。 堆:堆是向高地址擴展的數(shù)據(jù)結(jié)構(gòu),是不連續(xù)的內(nèi)存區(qū)域。這是由于系統(tǒng)是用鏈表來存儲的空閑內(nèi)存地址的,自然是不連續(xù)的,而鏈表的遍歷方向是由低地址向高地址。堆的大小受限于計算機系統(tǒng)中有效的虛擬內(nèi)存。由此可見,堆獲得的空間比較靈活,也比較大。 碎片問題:對于堆來講,頻繁的new/delete勢必會造成內(nèi)存空間的不連續(xù),從而造成大量的碎片,使程序效率降低。對于棧來講,則不會存在這個問題,因為棧是先進后出的隊列,他們是如此的一一對應(yīng),以至于

50、永遠都不可能有一個內(nèi)存塊從棧中間彈出 分配方式:堆都是動態(tài)分配的,沒有靜態(tài)分配的堆。棧有2種分配方式:靜態(tài)分配和動態(tài)分配。靜態(tài)分配是編譯器完成的,比如局部變量的分配。動態(tài)分配由alloca函數(shù)進行分配,但是棧的動態(tài)分配和堆是不同的,他的動態(tài)分配是由編譯器進行釋放,無需我們手工實現(xiàn)。 分配效率:棧是機器系統(tǒng)提供的數(shù)據(jù)結(jié)構(gòu),計算機會在底層對棧提供支持:分配專門的寄存器存放棧的地址,壓棧出棧都有專門的指令執(zhí)行,這就決定了棧的效率比較高。堆則是C/C+函數(shù)庫提供的,它的機制是很復(fù)雜的。5什么是鍵-值,鍵路徑是什么 模型的性質(zhì)是通過一個簡單的鍵(通常是個字符串)來指定的。視

51、圖和控制器通過鍵來查找相應(yīng)的屬性值。在一個給定的實體中,同一個屬性的所有值具有相同的數(shù)據(jù)類型。鍵-值編碼技術(shù)用于進行這樣的查找它是一種間接訪問對象屬性的機制。 鍵路徑是一個由用點作分隔符的鍵組成的字符串,用于指定一個連接在一起的對象性質(zhì)序列。第一個鍵的 性質(zhì)是由先前的性質(zhì)決定的,接下來每個鍵的值也是相對于其前面的性質(zhì)。鍵路徑使您可以以獨立于模型 實現(xiàn)的方式指定相關(guān)對象的性質(zhì)。通過鍵路徑,您可以指定對象圖中的一個任意深度的路徑,使其指向相 關(guān)對象的特定屬性。 6目標(biāo)-動作機制  目標(biāo)是動作消息的接收者。一個控件,或者更為常見的

52、是它的單元,以插座變量(參見"插座變量"部分) 的形式保有其動作消息的目標(biāo)。 動作是控件發(fā)送給目標(biāo)的消息,或者從目標(biāo)的角度看,它是目標(biāo)為了響應(yīng)動作而實現(xiàn)的方法。 程序需要某些機制來進行事件和指令的翻譯。這個機制就是目標(biāo)-動作機制。 7objc的內(nèi)存管理 ?  如果您通過分配和初始化(比如MyClass alloc init)的方式來創(chuàng)建對象,您就擁 有這個對象,需要負責(zé)該對象的釋放。這個規(guī)則在使用NSObject的便利方法new 時也同樣適用。 ?  如果

53、您拷貝一個對象,您也擁有拷貝得到的對象,需要負責(zé)該對象的釋放。 ?  如果您保持一個對象,您就部分擁有這個對象,需要在不再使用時釋放該對象。 反過來, ?  如果您從其它對象那里接收到一個對象,則您不擁有該對象,也不應(yīng)該釋放它(這個規(guī)則有少數(shù) 的例外,在參考文檔中有顯式的說明)。 8 自動釋放池是什么,如何工作 當(dāng)您向一個對象發(fā)送一個autorelease消息時,Cocoa就會將該對象的一個引用放入到最新的自動釋放池。它仍然是個正當(dāng)?shù)膶ο?,因此自動釋放池定義的作用域內(nèi)的其它對象可以向它

54、發(fā)送消息。當(dāng)程序執(zhí)行到作用域結(jié)束的位置時,自動釋放池就會被釋放,池中的所有對象也就被釋放。 1.  ojc-c 是通過一種"referring counting"(引用計數(shù))的方式來管理內(nèi)存的, 對象在開始分配內(nèi)存(alloc)的時候引用計數(shù)為一,以后每當(dāng)碰到有copy,retain的時候引用計數(shù)都會加一, 每當(dāng)碰到release和autorelease的時候引用計數(shù)就會減一,如果此對象的計數(shù)變?yōu)榱?, 就會被系統(tǒng)銷毀. 2. NSAutoreleasePool 就是用來做引用計數(shù)的管理工作的,

55、這個東西一般不用你管的. 3. autorelease和release沒什么區(qū)別,只是引用計數(shù)減一的時機不同而已,autorelease會在對象的使用真正結(jié)束的時候才做引用計數(shù)減一. 9類工廠方法是什么 類工廠方法的實現(xiàn)是為了向客戶提供方便,它們將分配和初始化合在一個步驟中,返回被創(chuàng)建的對象,并 進行自動釋放處理。這些方法的形式是+ (type)className.(其中 className不包括任何前綴)。 工廠方法可能不僅僅為了方便使用。它們不但可以將分配和初始化合在一起,還可以為初始化過程提供對 象的分配信息。

56、0;類工廠方法的另一個目的是使類(比如NSWorkspace)提供單件實例。雖然init.方法可以確認一 個類在每次程序運行過程只存在一個實例,但它需要首先分配一個“生的”實例,然后還必須釋放該實例。 工廠方法則可以避免為可能沒有用的對象盲目分配內(nèi)存。 10單件實例是什么 Foundation 和 Application Kit 框架中的一些類只允許創(chuàng)建單件對象,即這些類在當(dāng)前進程中的唯一實例。舉例來說,NSFileManager 和NSWorkspace 類在使用時都是基于進程進行單件對象的實例化。當(dāng)向

57、這些類請求實例的時候,它們會向您傳遞單一實例的一個引用,如果該實例還不存在,則首先進行實例的分配和初始化。單件對象充當(dāng)控制中心的角色,負責(zé)指引或協(xié)調(diào)類的各種服務(wù)。如果類在概念上只有一個實例(比如 NSWorkspace),就應(yīng)該產(chǎn)生一個單件實例,而不是多個實例;如果將來某一天可能有多個實例,您可 以使用單件實例機制,而不是工廠方法或函數(shù)。11動態(tài)綁定 在運行時確定要調(diào)用的方法  動態(tài)綁定將調(diào)用方法的確定也推遲到運行時。在編譯時,方法的調(diào)用并不和代碼綁定在一起,只有在消實發(fā)送出來之后,才確定被調(diào)用的代碼。通過動態(tài)類型和動態(tài)綁定技術(shù),您的代碼每次執(zhí)

58、行都可以得到不同的結(jié)果。運行時因子負責(zé)確定消息的接收者和被調(diào)用的方法。運行時的消息分發(fā)機制為動態(tài)綁定提供支持。當(dāng)您向一個動態(tài)類型確定了的對象發(fā)送消息時,運行環(huán)境系統(tǒng)會通過接收者的isa指針定位對象的類,并以此為起點確定被調(diào)用的方法,方法和消息是動態(tài)綁定的。而且,您不必在Objective-C 代碼中做任何工作,就可以自動獲取動態(tài)綁定的好處。您在每次發(fā)送消息時,  特別是當(dāng)消息的接收者是動態(tài)類型已經(jīng)確定的對象時,動態(tài)綁定就會例行而透明地發(fā)生。12obj-c的優(yōu)缺點 objc優(yōu)點:   1) Cateogies 

59、60; 2) Posing   3) 動態(tài)識別   4) 指標(biāo)計算   5)彈性訊息傳遞   6) 不是一個過度復(fù)雜的 C 衍生語言   7) Objective-C 與 C+ 可混合編程 缺點:   1) 不支援命名空間   2)  不支持運算符重載   3

60、)不支持多重繼承   4)使用動態(tài)運行時類型,所有的方法都是函數(shù)調(diào)用,所以很多編譯時優(yōu)化方法都用不到。(如內(nèi)聯(lián)函數(shù)等),性能低劣。 13sprintf,strcpy,memcpy使用上有什么要注意的地方 strcpy是一個字符串拷貝的函數(shù),它的函數(shù)原型為strcpy(char *dst, c*t char *src); 將 src開始的一段字符串拷貝到dst開始的內(nèi)存中去,結(jié)束的標(biāo)志符號為'0',由于拷貝的長度不是由我們自己控制的,所以這個字符串拷貝很容易出錯。具備字符串拷貝功能的函數(shù)有memcpy,這是一個

61、內(nèi)存拷貝函數(shù),它的函數(shù)原型為memcpy(char *dst, c*t char* src, unsigned int len); 將長度為len的一段內(nèi)存,從src拷貝到dst中去,這個函數(shù)的長度可控。但是會有內(nèi)存疊加的問題。 sprintf是格式化函數(shù)。將一段數(shù)據(jù)通過特定的格式,格式化到一個字符串緩沖區(qū)中去。sprintf格式化的函數(shù)的長度不可控,有可能格式化后的字符串會超出緩沖區(qū)的大小,造成溢出。 14答案是:   a) int a; / An integer   b) int *a; / A po

62、inter to an integer   c) int *a; / A pointer to a pointer to an integer   d) int a10; / An array of 10 integers   e) int *a10; / An array of 10 pointers to integers   f) int (*a)10; / A pointer to an array of 10 integers   g)

63、 int (*a)(int); / A pointer to a function a that  takes an integer argument and returns an integer   h) int (*a10)(int); / An array of 10 pointers to functi*  that take an integer argument and return an integer 15.readwrite,readonly,assign,retain,copy,nonatomic屬性的作用

64、0;property是一個屬性訪問聲明,擴號內(nèi)支持以下幾個屬性: 1,getter=getterName,setter=setterName,設(shè)置setter與getter的方法名 2,readwrite,readonly,設(shè)置可供訪問級別 2,assign,setter方法直接賦值,不進行任何retain操作,為了解決原類型與環(huán)循引用問題 3,retain,setter方法對參數(shù)進行release舊值再retain新值,所有實現(xiàn)都是這個順序(CC上有相關(guān)資料) 4,copy,setter方法進行Copy操作,與retain處理流程一樣,先舊值

65、release,再Copy出新的對象,retainCount為1。這是為了減少對上下文的依賴而引入的機制。 copy是在你不希望a和b共享一塊內(nèi)存時會使用到。a和b各自有自己的內(nèi)存。5,nonatomic,非原子性訪問,不加同步,多線程并發(fā)訪問會提高性能。注意,如果不加此屬性,則默認是兩個訪問方法都為原子型事務(wù)訪問。鎖被加到所屬對象實例級(我是這么理解的.)。atomic和nonatomic用來決定編譯器生成的getter和setter是否為原子操作。在多線程環(huán)境下,原子操作是必要的,否則有可能引起錯 誤的結(jié)果。加了atomic,setter函數(shù)會變成下面這樣:16什么時候用dele

66、gate,什么時候用Notification?答:delegate針對one-to-one關(guān)系,并且reciever可以返回值 給sender,notification 可以針對one-to-one/many/none,reciever無法返回值給sender.所以,delegate用于sender希望接受到 reciever的某個功能反饋值,notification用于通知多個object某個事件。 17什么是KVC和KVO?答:KVC(Key-Value-Coding)內(nèi)部的實現(xiàn):一個對象在調(diào)用setValue的時候,(1)首先根據(jù)方法名找到運行方法

67、的時候所需要的環(huán)境參數(shù)。(2)他會從自己isa指針結(jié)合環(huán)境參數(shù),找到具體的方法實現(xiàn)的接口。(3)再直接查找得來的具體的方法實現(xiàn)。KVO(Key-Value- Observing):當(dāng)觀察者為一個對象的屬性進行了注冊,被觀察對象的isa指針被修改的時候,isa指針就會指向一個中間類,而不是真實的類。所以 isa指針其實不需要指向?qū)嵗龑ο笳鎸嵉念?。所以我們的程序最好不要依賴于isa指針。在調(diào)用類的方法的時候,最好要明確對象實例的類名18ViewController 的 loadView, viewDidLoad, viewDidUnload 分別是在什么時候

68、調(diào)用的?在自定義ViewController的時候這幾個函數(shù)里面應(yīng)該做什么工作?答:viewDidLoad在view 從nib文件初始化時調(diào)用,loadView在controller的view為nil時調(diào)用。此方法在編程實現(xiàn)view時調(diào)用,view 控制器默認會注冊memory warning notification,當(dāng)view controller的任何view 沒有用的時候,viewDidUnload會被調(diào)用,在這里實現(xiàn)將retain 的view release,如果是retain的IBOutlet view 屬性則不要在這里release,IBOutlet會負責(zé)release 。19"NSMutableString *"這個數(shù)據(jù)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論