版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、史上最全的iOS面試題及答案 iOS面試小貼士回答好下面的足夠了-多線程、特別是NSOperation 和 GCD 的內(nèi)部原理。運(yùn)行時(shí)機(jī)制的原理和運(yùn)用場(chǎng)景。SDWebImage的原理。實(shí)現(xiàn)機(jī)制。如何解決TableView卡的問(wèn)題。block和代理的,通知的區(qū)別。block的用法需要注意些什么。strong,weak,retain,assign,copy nomatic 等的區(qū)別。設(shè)計(jì)模式,mvc,單利,工廠,代理等的應(yīng)用場(chǎng)景。單利的寫法。在單利中創(chuàng)建數(shù)組應(yīng)該注意些什么。NSString 的時(shí)候用copy和strong的區(qū)別。響應(yīng)值鏈。NSTimer 在子線程中應(yīng)該手動(dòng)創(chuàng)建
2、NSRunLoop ,否則不能循環(huán)執(zhí)行。UIScrollView和NSTimer組合做循環(huán)廣告圖輪播的時(shí)候有一個(gè)屬性可以控制當(dāng)上下滾動(dòng)tableview的時(shí)候廣告輪播圖依然正常滾動(dòng)。Xcode最新的自動(dòng)布局。這個(gè)很多公司都用。盡量自學(xué)下。git ,和svn的用法。git的幾個(gè)命令簡(jiǎn)單的記下。友盟報(bào)錯(cuò)可以查到具體某一行的錯(cuò)誤,原理是什么。Instrument 可以檢測(cè) 電池的耗電量、和內(nèi)存的消耗。的用法。動(dòng)畫CABaseAnimation CAKeyAni. CATrans. CAGoup. 等熟悉。ARC的原理。自己寫過(guò)什么自定義控
3、件就最好了。 回答好上面的足夠了- _block和_weak修飾符的區(qū)別其實(shí)是挺明顯的: 1._block不管是ARC還是MRC模式下都可以使用,可以修飾對(duì)象,還可以修飾基本數(shù)據(jù)類型。 2._weak只能在ARC模式下使用,也只能修飾對(duì)象(NSString),不能修飾基本數(shù)據(jù)類型(int)。 3._block對(duì)象可以在block中被重新賦值,_weak不可以。 tableView 滑動(dòng)卡的問(wèn)題主要是因?yàn)椋簭木彺嬷谢蛘呤菑谋镜刈x取圖片給UIImage的時(shí)候耗費(fèi)的時(shí)間。需要把下面的兩句話放到子線程里面:1. NSD
4、ata *imgData = NSData dataWithContentsOfURL:NSURL URLWithString:app.icon; /得到圖像數(shù)據(jù) 2. UIImage *image = UIImage imageWithData:imgData; 把UIImage賦值給圖片的時(shí)候在主線程。子線程不能更新UI 所有的UI跟新都是主線程執(zhí)行了
5、。手指滑動(dòng)屏幕了。或者屏幕的某個(gè)方法執(zhí)行了。 子線程里面加入NSTimer 的時(shí)候需要 手動(dòng)添加NSRunloop 否則不能循環(huán)。 單利里面添加 NSMutableArray 的時(shí)候,防止多個(gè)地方對(duì)它同時(shí)便利和修改的話,需要加原子屬性。并且用strong,并且寫一個(gè)遍歷和修改的方法。加上鎖。 Lock UnLock _weak ViewController* weakSelf = self;GCD里面用 _weak 防止內(nèi)存釋放不了,循環(huán)引用。
6、 二、SDWebImage內(nèi)部實(shí)現(xiàn)過(guò)程1. 入口 setImageWithURL:placeholderImage:options: 會(huì)先把 placeholderImage 顯示,然后 SDWebImageManager 根據(jù) URL 開始處理圖片。2. 進(jìn)入 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 添加到隊(duì)列開始從硬盤查找圖片是否已經(jīng)緩存。6. 根據(jù) URLKey 在硬盤緩存目錄下嘗試讀取圖片文件。這一步是在 NSOperati
8、on 進(jìn)行的操作,所以回主線程進(jìn)行結(jié)果回調(diào) notifyDelegate:。7. 如果上一操作從硬盤讀取到了圖片,將圖片添加到內(nèi)存緩存中(如果空閑內(nèi)存過(guò)小,會(huì)先清空內(nèi)存緩存)。SDImageCacheDelegate 回調(diào) imageCache:didFindImage:forKey:userInfo:。進(jìn)而回調(diào)展示圖片。8. 如果從硬盤緩存目錄讀取不到圖片,說(shuō)明所有緩存都不存在該圖片,需要下載圖片,回調(diào) imageCache:didNotFindImageForKey:userInfo:。9. 共享或重新生成一個(gè)下載器 SDWebImageDownloader 開始下載圖片。10. 圖片下載
9、由 NSURLConnection 來(lái)做,實(shí)現(xiàn)相關(guān) delegate 來(lái)判斷圖片下載中、下載完成和下載失敗。11. connection:didReceiveData: 中利用 ImageIO 做了按圖片下載進(jìn)度加載效果。12. connectionDidFinishLoading: 數(shù)據(jù)下載完成后交給 SDWebImageDecoder 做圖片解碼處理。13. 圖片解碼處理在一個(gè) NSOperationQueue 完成,不會(huì)拖慢主線程 UI。如果有需要對(duì)下載的圖片進(jìn)行二次處理,最好也在這里完成,效率會(huì)好很多。14. 在主線程 notifyDelegateOnMainThreadWithInf
10、o: 宣告解碼完成,imageDecoder:didFinishDecodingImage:userInfo: 回調(diào)給 SDWebImageDownloader。15. imageDownloader:didFinishWithImage: 回調(diào)給 SDWebImageManager 告知圖片下載完成。16. 通知所有的 downloadDelegates 下載完成,回調(diào)給需要的地方展示圖片。17. 將圖片保存到 SDImageCache 中,內(nèi)存緩存和硬盤緩存同時(shí)保存。寫文件到硬盤也在以單獨(dú) NSInvocationOperation 完成,避免拖慢主線程。18. SDImageCache
11、在初始化的時(shí)候會(huì)注冊(cè)一些消息通知,在內(nèi)存警告或退到后臺(tái)的時(shí)候清理內(nèi)存圖片緩存,應(yīng)用結(jié)束的時(shí)候清理過(guò)期圖片。19. SDWI 也提供了 UIButton+WebCache 和 MKAnnotationView+WebCache,方便使用。20. SDWebImagePrefetcher 可以預(yù)先下載圖片,方便后續(xù)使用。從上面流程可以看出,當(dāng)你調(diào)用setImageWithURL:方法的時(shí)候,他會(huì)自動(dòng)去給你干這么多事,當(dāng)你需要在某一具體時(shí)刻做事情的時(shí)候,你可以覆蓋這些方法。比如在下載某個(gè)圖片的過(guò)程中要響應(yīng)一個(gè)事件,就覆蓋這個(gè)方法:1234567891011/覆蓋方法,指哪打哪,這個(gè)方法是下載imag
12、ePath2的時(shí)候響應(yīng) SDWebImageManager *manager = SDWebImageManager sharedManager; manager downloadImageWithURL:imagePath2 options:SDWebImageRetryFailed progress:(NSInteger receivedSize,
13、NSInteger expectedSize) NSLog("顯示當(dāng)前進(jìn)度"); completed:(UIImage *image, NSError *e
14、rror, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) NSLog("下載完成"); 對(duì)于初級(jí)來(lái)說(shuō),用sd_setImageWithURL:的若干個(gè)方法就可以實(shí)現(xiàn)很好的圖片緩存。
15、 UIButton 的父類是UIControl UIControl的父類是UIView UIView的父類是 UIResponder http狀態(tài)嗎 :302 是請(qǐng)求重定向。500以上是服務(wù)器錯(cuò)誤。400以上是請(qǐng)求鏈接錯(cuò)誤或者找不到服務(wù)器。200以上是正確。100以上是請(qǐng)求接受成功。 HTTP Keep-Alive詳解轉(zhuǎn)HTTP是一個(gè)請(qǐng)求<->響應(yīng)模式的典型范例,即客戶端向服務(wù)器發(fā)送一個(gè)請(qǐng)求信息,服務(wù)器來(lái)響應(yīng)這個(gè)信息。在老的HTTP版本中,每個(gè)請(qǐng)求都將被創(chuàng)建一個(gè)新的客戶端->服務(wù)器的連接,在這個(gè)連接上發(fā)送請(qǐng)求,然后接收請(qǐng)求
16、。這樣的模式有一個(gè)很大的優(yōu)點(diǎn)就是,它很簡(jiǎn)單,很容易理解和編程實(shí)現(xiàn);它也有一個(gè)很大的缺點(diǎn)就是,它效率很低,因此Keep-Alive被提出用來(lái)解決效率低的問(wèn)題。Keep-Alive功能使客戶端到服務(wù)器端的連接持續(xù)有效,當(dāng)出現(xiàn)對(duì)服務(wù)器的后繼請(qǐng)求時(shí),Keep-Alive功能避免了建立或者重新建立連接。市場(chǎng)上 的大部分Web服務(wù)器,包括iPlanet、IIS和Apache,都支持HTTP Keep-Alive。對(duì)于提供靜態(tài)內(nèi)容的網(wǎng)站來(lái)說(shuō),這個(gè)功能通常很有用。但是,對(duì)于負(fù)擔(dān)較重的網(wǎng)站來(lái)說(shuō),這里存在另外一個(gè)問(wèn)題:雖然為客戶保留打開的連 接有一定的好處,但它同樣影響了性能,因?yàn)樵谔幚頃和F陂g,本來(lái)可
17、以釋放的資源仍舊被占用。當(dāng)Web服務(wù)器和應(yīng)用服務(wù)器在同一臺(tái)機(jī)器上運(yùn)行時(shí),Keep- Alive功能對(duì)資源利用的影響尤其突出。 此功能為HTTP 1.1預(yù)設(shè)的功能,HTTP 1.0加上Keep-Aliveheader也可以提供HTTP的持續(xù)作用功能。Keep-Alive: timeout=5, max=100timeout:過(guò)期時(shí)間5秒(對(duì)應(yīng)httpd.conf里的參數(shù)是:KeepAliveTimeout),max是最多一百次請(qǐng)求,強(qiáng)制斷掉連接就是在timeout時(shí)間內(nèi)又有新的連接過(guò)來(lái),同時(shí)max會(huì)自動(dòng)減1,直到為0,強(qiáng)制斷掉。見下面的四個(gè)圖,注意看Date的值(前后時(shí)間差都是在5秒之
18、內(nèi))!HTTP/1.0在HTTP/1.0版本中,并沒有官方的標(biāo)準(zhǔn)來(lái)規(guī)定Keep-Alive如何工作,因此實(shí)際上它是被附加到HTTP/1.0協(xié)議上,如果客戶端瀏覽器支持Keep-Alive,那么就在HTTP請(qǐng)求頭中添加一個(gè)字段 Connection: Keep-Alive,當(dāng)服務(wù)器收到附帶有Connection: Keep-Alive的請(qǐng)求時(shí),它也會(huì)在響應(yīng)頭中添加一個(gè)同樣的字段來(lái)使用Keep-Alive。這樣一來(lái),客戶端和服務(wù)器之間的HTTP連接就會(huì)被保持,不會(huì)斷開(超過(guò)Keep-Alive規(guī)定的時(shí)間,意外斷電等情況除外),當(dāng)客戶端發(fā)送另外一個(gè)請(qǐng)求時(shí),就使用這條已經(jīng)建立的連接HTTP/
19、1.1在HTTP/1.1版本中,官方規(guī)定的Keep-Alive使用標(biāo)準(zhǔn)和在HTTP/1.0版本中有些不同,默認(rèn)情況下所在HTTP1.1中所有連接都被保持,除非在請(qǐng)求頭或響應(yīng)頭中指明要關(guān)閉:Connection: Close ,這也就是為什么Connection: Keep-Alive字段再?zèng)]有意義的原因。另外,還添加了一個(gè)新的字段Keep-Alive:,因?yàn)檫@個(gè)字段并沒有詳細(xì)描述用來(lái)做什么,可忽略它Not reliable(不可靠)HTTP是一個(gè)無(wú)狀態(tài)協(xié)議,這意味著每個(gè)請(qǐng)求都是獨(dú)立的,Keep-Alive沒能改變這個(gè)結(jié)果。另外,Keep-Alive也不能保證客戶端和服務(wù)器之間的連接
20、一定是活躍的,在HTTP1.1版本中也如此。唯一能保證的就是當(dāng)連接被關(guān)閉時(shí)你能得到一個(gè)通知,所以不應(yīng)該讓程序依賴于Keep-Alive的保持連接特性,否則會(huì)有意想不到的后果Keep-Alive和POST在HTTP1.1細(xì)則中規(guī)定了在一個(gè)POST消息體后面不能有任何字符,還指出了對(duì)于某一個(gè)特定的瀏覽器可能并不遵循這個(gè)標(biāo)準(zhǔn)(比如在POST消息體的后面放置一個(gè)CRLF符)。而據(jù)我所知,大部分瀏覽器在POST消息體后都會(huì)自動(dòng)跟一個(gè)CRLF符再發(fā)送,如何解決這個(gè)問(wèn)題呢?根據(jù)上面的說(shuō)明在POST請(qǐng)求頭中禁止使用Keep-Alive,或者由服務(wù)器自動(dòng)忽略這個(gè)CRLF,大部分服務(wù)器都會(huì)自動(dòng)忽略,但是在未經(jīng)測(cè)試
21、之前是不可能知道一個(gè)服務(wù)器是否會(huì)這樣做。 1、常用的方法dispatch_async為了避免界面在處理耗時(shí)的操作時(shí)卡死,比如讀取網(wǎng)絡(luò)數(shù)據(jù),IO,數(shù)據(jù)庫(kù)讀寫等,我們會(huì)在另外一個(gè)線程中處理這些操作,然后通知主線程更新界面。用GCD實(shí)現(xiàn)這個(gè)流程的操作比前面介紹的NSThread NSOperation的方法都要簡(jiǎn)單。代碼框架結(jié)構(gòu)如下: 1. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), 2.
22、 / 耗時(shí)的操作 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. ); 運(yùn)行顯示:是不是代碼比NSThread NSOpe
26、ration簡(jiǎn)潔很多,而且GCD會(huì)自動(dòng)根據(jù)任務(wù)在多核處理器上分配資源,優(yōu)化程序。系統(tǒng)給每一個(gè)應(yīng)用程序提供了三個(gè)concurrent dispatch queues。這三個(gè)并發(fā)調(diào)度隊(duì)列是全局的,它們只有優(yōu)先級(jí)的不同。因?yàn)槭侨值?,我們不需要去?chuàng)建。我們只需要通過(guò)使用函數(shù)dispath_get_global_queue去得到隊(duì)列,如下: 1. dispatch_queue_t globalQ = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
27、60; 這里也用到了系統(tǒng)默認(rèn)就有一個(gè)串行隊(duì)列main_queue 1. dispatch_queue_t mainQ = dispatch_get_main_queue(); 雖然dispatch queue是引用計(jì)數(shù)的對(duì)象,但是以上兩個(gè)都是全局的隊(duì)列,不用retain或release。2、dispatch_group_async的使用dispatch_group_async可以實(shí)現(xiàn)監(jiān)聽一組任務(wù)是否完成,完成后得到通知執(zhí)行其他的操作。這個(gè)方法很有用,比如你執(zhí)行三個(gè)下載任務(wù),當(dāng)
28、三個(gè)任務(wù)都下載完成后你才通知界面說(shuō)完成的了。下面是一段例子代碼: 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是異步的方法,運(yùn)行后可以看到打印結(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每個(gè)一秒打印一個(gè),當(dāng)?shù)谌齻€(gè)任務(wù)執(zhí)行后,upadteUi被打印。 3、dispatch_barrier_async的使用dispatch_barrier_async是在前面的任務(wù)執(zhí)行結(jié)束后它才執(zhí)行,而且它后面的任務(wù)等它執(zhí)行完成之后才會(huì)執(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請(qǐng)注意執(zhí)行的時(shí)間,可以看到執(zhí)行的順序如上所述。4、dispatch_apply 執(zhí)行某個(gè)代碼片段N次。dispatch_apply(5, globalQ, (size_t index) / 執(zhí)行5次); copy與retain:1、copy其實(shí)是建立了一個(gè)相同的對(duì)象,而retain不是;2、copy是內(nèi)容拷貝,retain是指針拷貝; 3、copy是內(nèi)容的拷貝 ,對(duì)于像NSString,的確是這樣,但是如果copy
38、的是一個(gè)NSArray呢?這時(shí)只是copy了指向array中相對(duì)應(yīng)元素的指針.這便是所謂的"淺復(fù)制".4、copy的情況:NSString *newPt = pt copy;此時(shí)會(huì)在堆上重新開辟一段內(nèi)存存放"abc" 比如0X1122 內(nèi)容為"abc 同時(shí)會(huì)在棧上為newPt分配空間 比如地址:0Xaacc 內(nèi)容為0X1122 因此retainCount增加1供newPt來(lái)管理0X1122這段內(nèi)存;assign與retain:1、assign: 簡(jiǎn)單賦值,不更改索引計(jì)數(shù);2、assign的情況:NSString *newPt = pt assi
39、ng; 此時(shí)newPt和pt完全相同 地址都是0Xaaaa 內(nèi)容為0X1111 即newPt只是pt的別名,對(duì)任何一個(gè)操作就等于對(duì)另一個(gè)操作, 因此retainCount不需要增加;3、assign就是直接賦值;4、retain使用了引用計(jì)數(shù),retain引起引用計(jì)數(shù)加1, release引起引用計(jì)數(shù)減1,當(dāng)引用計(jì)數(shù)為0時(shí),dealloc函數(shù)被調(diào)用,內(nèi)存被回收; 5、retain的情況:NSString *newPt = pt retain; 此時(shí)newPt的地址不再為0Xaaaa,可能為0Xaabb 但是內(nèi)容依然為0X1111
40、。 因此newPt 和 pt 都可以管理"abc"所在的內(nèi)存,因此 retainCount需要增加1 ;readonly:1、屬性是只讀的,默認(rèn)的標(biāo)記是讀寫,如果你指定了只讀,在implementation中只需要一個(gè)讀取器?;蛘呷绻闶褂胹ynthesize關(guān)鍵字,也是有讀取器方法被解析 readwrite:1、說(shuō)明屬性會(huì)被當(dāng)成讀寫的,這也是默認(rèn)屬性。設(shè)置器和讀取器都需要在implementation中實(shí)現(xiàn)。如果使用synthesize關(guān)鍵字,讀取器和設(shè)置器都會(huì)被解析;nonatomic:1、非原子性訪問(wèn),對(duì)屬性賦值的時(shí)候不加鎖,多線程并發(fā)
41、訪問(wèn)會(huì)提高性能。如果不加此屬性,則默認(rèn)是兩個(gè)訪問(wèn)方法都為原子型事務(wù)訪問(wèn);weak and strong property (強(qiáng)引用和弱引用的區(qū)別):1、 weak 和 strong 屬性只有在你打開ARC時(shí)才會(huì)被要求使用,這時(shí)你是不能使用retain release autorelease 操作的,因?yàn)锳RC會(huì)自動(dòng)為你做好這些操作,但是你需要在對(duì)象屬性上使用weak 和strong,其中strong就相當(dāng)于retain屬性,而weak相當(dāng)于assign。2、只有一種情況你需要使用weak(默認(rèn)是strong),就是為了避免retain cycles(就是父類中含有子類父類retain
42、了子類,子類中又調(diào)用了父類子類又retain了父類,這樣都無(wú)法release) 3、聲明為weak的指針,指針指向的地址一旦被釋放,這些指針都將被賦值為nil。這樣的好處能有效的防止野指針。 ARC(Automatic Reference Counting):1、就是代碼中自動(dòng)加入了retain/release,原先需要手動(dòng)添加的用來(lái)處理內(nèi)存管理的引用計(jì)數(shù)的代碼可以自動(dòng)地由編譯器完成了。該機(jī)能在 iOS 5/ Mac OS X 10.7 開始導(dǎo)入,利用 Xcode4.2 以后可以使用該特性。strong
43、,weak,copy 具體用法:1.具體一點(diǎn):IBOutlet可以為weak,NSString為copy,Delegate一般為weak,其他的看情況。一般來(lái)說(shuō),類“內(nèi)部”的屬性設(shè)置為strong,類“外部”的屬性設(shè)置為weak。說(shuō)到底就是一個(gè)歸屬權(quán)的問(wèn)題。小心出現(xiàn)循環(huán)引用導(dǎo)致內(nèi)存無(wú)法釋放。2.不用ARC的話就會(huì)看到很多retian。3.如果你寫了synthesize abc = _abc;的話,系統(tǒng)自動(dòng)幫你聲明了一個(gè)_abc的實(shí)例變量。 使用assign: 對(duì)基礎(chǔ)數(shù)據(jù)類型 (NSInteger)和C數(shù)據(jù)類型(int, float, double, char,等)
44、60; 使用copy: 對(duì)NSString 使用retain: 對(duì)其他NSObject和其子類 1. 1.寫一個(gè)NSString類的實(shí)現(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)用時(shí)仍維持上次的值; (2)在模塊內(nèi)的 static 全局變量可以被模塊內(nèi)所用函數(shù)訪問(wèn),但不能被模塊外其它函數(shù)訪問(wèn); (3)在模塊內(nèi)的 static 函數(shù)只可被這一模塊內(nèi)的其它函數(shù)調(diào)用,這個(gè)函數(shù)的使用范圍被限制在聲明 它的模塊內(nèi); (4)在類中的 sta
47、tic 成員變量屬于整個(gè)類所擁有,對(duì)類的所有對(duì)象只有一份拷貝; (5)在類中的 static 成員函數(shù)屬于整個(gè)類所擁有,這個(gè)函數(shù)不接收 this 指針,因而只能訪問(wèn)類的static 成員變量。 3線程與進(jìn)程的區(qū)別和聯(lián)系? 進(jìn)程和線程都是由操作系統(tǒng)所體會(huì)的程序運(yùn)行的基本單元,系統(tǒng)利用該基本單元實(shí)現(xiàn)系統(tǒng)對(duì)應(yīng)用的并發(fā)性。 程和線程的主要差別在于它們是不同的操作系統(tǒng)資源管理方式。進(jìn)程有獨(dú)立的地址空間,一個(gè)進(jìn)程崩潰后,在保護(hù)模式下不會(huì)對(duì)其它進(jìn)程產(chǎn)生影響,而線程只是一個(gè)進(jìn)程中的不同執(zhí)行路徑。線程
48、有自己的堆棧和局部變量,但線程之間沒有單獨(dú)的地址空間,一個(gè)線程死掉就等于整個(gè)進(jìn)程死掉,所以多進(jìn)程的程序要比多線程的程序健壯,但在進(jìn)程切換時(shí),耗費(fèi)資源較大,效率要差一些。但對(duì)于一些要求同時(shí)進(jìn)行并且又要共享某些變量的并發(fā)操作,只能用線程,不能用進(jìn)程。4堆和棧的區(qū)別 管理方式:對(duì)于棧來(lái)講,是由編譯器自動(dòng)管理,無(wú)需我們手工控制;對(duì)于堆來(lái)說(shuō),釋放工作由程序員控制,容易產(chǎn)生memory leak。 申請(qǐng)大?。?#160;棧:在Windows下,棧是向低地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu),是一塊連續(xù)的內(nèi)存的區(qū)域。這句話的意思是棧頂?shù)牡刂泛蜅5淖畲笕萘渴窍到y(tǒng)預(yù)先規(guī)定好的,在 WINDOWS下,棧
49、的大小是2M(也有的說(shuō)是1M,總之是一個(gè)編譯時(shí)就確定的常數(shù)),如果申請(qǐng)的空間超過(guò)棧的剩余空間時(shí),將提示overflow。因此,能從棧獲得的空間較小。 堆:堆是向高地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu),是不連續(xù)的內(nèi)存區(qū)域。這是由于系統(tǒng)是用鏈表來(lái)存儲(chǔ)的空閑內(nèi)存地址的,自然是不連續(xù)的,而鏈表的遍歷方向是由低地址向高地址。堆的大小受限于計(jì)算機(jī)系統(tǒng)中有效的虛擬內(nèi)存。由此可見,堆獲得的空間比較靈活,也比較大。 碎片問(wèn)題:對(duì)于堆來(lái)講,頻繁的new/delete勢(shì)必會(huì)造成內(nèi)存空間的不連續(xù),從而造成大量的碎片,使程序效率降低。對(duì)于棧來(lái)講,則不會(huì)存在這個(gè)問(wèn)題,因?yàn)闂J窍冗M(jìn)后出的隊(duì)列,他們是如此的一一對(duì)應(yīng),以至于
50、永遠(yuǎn)都不可能有一個(gè)內(nèi)存塊從棧中間彈出 分配方式:堆都是動(dòng)態(tài)分配的,沒有靜態(tài)分配的堆。棧有2種分配方式:靜態(tài)分配和動(dòng)態(tài)分配。靜態(tài)分配是編譯器完成的,比如局部變量的分配。動(dòng)態(tài)分配由alloca函數(shù)進(jìn)行分配,但是棧的動(dòng)態(tài)分配和堆是不同的,他的動(dòng)態(tài)分配是由編譯器進(jìn)行釋放,無(wú)需我們手工實(shí)現(xiàn)。 分配效率:棧是機(jī)器系統(tǒng)提供的數(shù)據(jù)結(jié)構(gòu),計(jì)算機(jī)會(huì)在底層對(duì)棧提供支持:分配專門的寄存器存放棧的地址,壓棧出棧都有專門的指令執(zhí)行,這就決定了棧的效率比較高。堆則是C/C+函數(shù)庫(kù)提供的,它的機(jī)制是很復(fù)雜的。5什么是鍵-值,鍵路徑是什么 模型的性質(zhì)是通過(guò)一個(gè)簡(jiǎn)單的鍵(通常是個(gè)字符串)來(lái)指定的。視
51、圖和控制器通過(guò)鍵來(lái)查找相應(yīng)的屬性值。在一個(gè)給定的實(shí)體中,同一個(gè)屬性的所有值具有相同的數(shù)據(jù)類型。鍵-值編碼技術(shù)用于進(jìn)行這樣的查找它是一種間接訪問(wèn)對(duì)象屬性的機(jī)制。 鍵路徑是一個(gè)由用點(diǎn)作分隔符的鍵組成的字符串,用于指定一個(gè)連接在一起的對(duì)象性質(zhì)序列。第一個(gè)鍵的 性質(zhì)是由先前的性質(zhì)決定的,接下來(lái)每個(gè)鍵的值也是相對(duì)于其前面的性質(zhì)。鍵路徑使您可以以獨(dú)立于模型 實(shí)現(xiàn)的方式指定相關(guān)對(duì)象的性質(zhì)。通過(guò)鍵路徑,您可以指定對(duì)象圖中的一個(gè)任意深度的路徑,使其指向相 關(guān)對(duì)象的特定屬性。 6目標(biāo)-動(dòng)作機(jī)制 目標(biāo)是動(dòng)作消息的接收者。一個(gè)控件,或者更為常見的
52、是它的單元,以插座變量(參見"插座變量"部分) 的形式保有其動(dòng)作消息的目標(biāo)。 動(dòng)作是控件發(fā)送給目標(biāo)的消息,或者從目標(biāo)的角度看,它是目標(biāo)為了響應(yīng)動(dòng)作而實(shí)現(xiàn)的方法。 程序需要某些機(jī)制來(lái)進(jìn)行事件和指令的翻譯。這個(gè)機(jī)制就是目標(biāo)-動(dòng)作機(jī)制。 7objc的內(nèi)存管理 ? 如果您通過(guò)分配和初始化(比如MyClass alloc init)的方式來(lái)創(chuàng)建對(duì)象,您就擁 有這個(gè)對(duì)象,需要負(fù)責(zé)該對(duì)象的釋放。這個(gè)規(guī)則在使用NSObject的便利方法new 時(shí)也同樣適用。 ? 如果
53、您拷貝一個(gè)對(duì)象,您也擁有拷貝得到的對(duì)象,需要負(fù)責(zé)該對(duì)象的釋放。 ? 如果您保持一個(gè)對(duì)象,您就部分擁有這個(gè)對(duì)象,需要在不再使用時(shí)釋放該對(duì)象。 反過(guò)來(lái), ? 如果您從其它對(duì)象那里接收到一個(gè)對(duì)象,則您不擁有該對(duì)象,也不應(yīng)該釋放它(這個(gè)規(guī)則有少數(shù) 的例外,在參考文檔中有顯式的說(shuō)明)。 8 自動(dòng)釋放池是什么,如何工作 當(dāng)您向一個(gè)對(duì)象發(fā)送一個(gè)autorelease消息時(shí),Cocoa就會(huì)將該對(duì)象的一個(gè)引用放入到最新的自動(dòng)釋放池。它仍然是個(gè)正當(dāng)?shù)膶?duì)象,因此自動(dòng)釋放池定義的作用域內(nèi)的其它對(duì)象可以向它
54、發(fā)送消息。當(dāng)程序執(zhí)行到作用域結(jié)束的位置時(shí),自動(dòng)釋放池就會(huì)被釋放,池中的所有對(duì)象也就被釋放。 1. ojc-c 是通過(guò)一種"referring counting"(引用計(jì)數(shù))的方式來(lái)管理內(nèi)存的, 對(duì)象在開始分配內(nèi)存(alloc)的時(shí)候引用計(jì)數(shù)為一,以后每當(dāng)碰到有copy,retain的時(shí)候引用計(jì)數(shù)都會(huì)加一, 每當(dāng)碰到release和autorelease的時(shí)候引用計(jì)數(shù)就會(huì)減一,如果此對(duì)象的計(jì)數(shù)變?yōu)榱?, 就會(huì)被系統(tǒng)銷毀. 2. NSAutoreleasePool 就是用來(lái)做引用計(jì)數(shù)的管理工作的,
55、這個(gè)東西一般不用你管的. 3. autorelease和release沒什么區(qū)別,只是引用計(jì)數(shù)減一的時(shí)機(jī)不同而已,autorelease會(huì)在對(duì)象的使用真正結(jié)束的時(shí)候才做引用計(jì)數(shù)減一. 9類工廠方法是什么 類工廠方法的實(shí)現(xiàn)是為了向客戶提供方便,它們將分配和初始化合在一個(gè)步驟中,返回被創(chuàng)建的對(duì)象,并 進(jìn)行自動(dòng)釋放處理。這些方法的形式是+ (type)className.(其中 className不包括任何前綴)。 工廠方法可能不僅僅為了方便使用。它們不但可以將分配和初始化合在一起,還可以為初始化過(guò)程提供對(duì) 象的分配信息。
56、0;類工廠方法的另一個(gè)目的是使類(比如NSWorkspace)提供單件實(shí)例。雖然init.方法可以確認(rèn)一 個(gè)類在每次程序運(yùn)行過(guò)程只存在一個(gè)實(shí)例,但它需要首先分配一個(gè)“生的”實(shí)例,然后還必須釋放該實(shí)例。 工廠方法則可以避免為可能沒有用的對(duì)象盲目分配內(nèi)存。 10單件實(shí)例是什么 Foundation 和 Application Kit 框架中的一些類只允許創(chuàng)建單件對(duì)象,即這些類在當(dāng)前進(jìn)程中的唯一實(shí)例。舉例來(lái)說(shuō),NSFileManager 和NSWorkspace 類在使用時(shí)都是基于進(jìn)程進(jìn)行單件對(duì)象的實(shí)例化。當(dāng)向
57、這些類請(qǐng)求實(shí)例的時(shí)候,它們會(huì)向您傳遞單一實(shí)例的一個(gè)引用,如果該實(shí)例還不存在,則首先進(jìn)行實(shí)例的分配和初始化。單件對(duì)象充當(dāng)控制中心的角色,負(fù)責(zé)指引或協(xié)調(diào)類的各種服務(wù)。如果類在概念上只有一個(gè)實(shí)例(比如 NSWorkspace),就應(yīng)該產(chǎn)生一個(gè)單件實(shí)例,而不是多個(gè)實(shí)例;如果將來(lái)某一天可能有多個(gè)實(shí)例,您可 以使用單件實(shí)例機(jī)制,而不是工廠方法或函數(shù)。11動(dòng)態(tài)綁定 在運(yùn)行時(shí)確定要調(diào)用的方法 動(dòng)態(tài)綁定將調(diào)用方法的確定也推遲到運(yùn)行時(shí)。在編譯時(shí),方法的調(diào)用并不和代碼綁定在一起,只有在消實(shí)發(fā)送出來(lái)之后,才確定被調(diào)用的代碼。通過(guò)動(dòng)態(tài)類型和動(dòng)態(tài)綁定技術(shù),您的代碼每次執(zhí)
58、行都可以得到不同的結(jié)果。運(yùn)行時(shí)因子負(fù)責(zé)確定消息的接收者和被調(diào)用的方法。運(yùn)行時(shí)的消息分發(fā)機(jī)制為動(dòng)態(tài)綁定提供支持。當(dāng)您向一個(gè)動(dòng)態(tài)類型確定了的對(duì)象發(fā)送消息時(shí),運(yùn)行環(huán)境系統(tǒng)會(huì)通過(guò)接收者的isa指針定位對(duì)象的類,并以此為起點(diǎn)確定被調(diào)用的方法,方法和消息是動(dòng)態(tài)綁定的。而且,您不必在Objective-C 代碼中做任何工作,就可以自動(dòng)獲取動(dòng)態(tài)綁定的好處。您在每次發(fā)送消息時(shí), 特別是當(dāng)消息的接收者是動(dòng)態(tài)類型已經(jīng)確定的對(duì)象時(shí),動(dòng)態(tài)綁定就會(huì)例行而透明地發(fā)生。12obj-c的優(yōu)缺點(diǎn) objc優(yōu)點(diǎn): 1) Cateogies
59、60; 2) Posing 3) 動(dòng)態(tài)識(shí)別 4) 指標(biāo)計(jì)算 5)彈性訊息傳遞 6) 不是一個(gè)過(guò)度復(fù)雜的 C 衍生語(yǔ)言 7) Objective-C 與 C+ 可混合編程 缺點(diǎn): 1) 不支援命名空間 2) 不支持運(yùn)算符重載 3
60、)不支持多重繼承 4)使用動(dòng)態(tài)運(yùn)行時(shí)類型,所有的方法都是函數(shù)調(diào)用,所以很多編譯時(shí)優(yōu)化方法都用不到。(如內(nèi)聯(lián)函數(shù)等),性能低劣。 13sprintf,strcpy,memcpy使用上有什么要注意的地方 strcpy是一個(gè)字符串拷貝的函數(shù),它的函數(shù)原型為strcpy(char *dst, c*t char *src); 將 src開始的一段字符串拷貝到dst開始的內(nèi)存中去,結(jié)束的標(biāo)志符號(hào)為'0',由于拷貝的長(zhǎng)度不是由我們自己控制的,所以這個(gè)字符串拷貝很容易出錯(cuò)。具備字符串拷貝功能的函數(shù)有memcpy,這是一個(gè)
61、內(nèi)存拷貝函數(shù),它的函數(shù)原型為memcpy(char *dst, c*t char* src, unsigned int len); 將長(zhǎng)度為len的一段內(nèi)存,從src拷貝到dst中去,這個(gè)函數(shù)的長(zhǎng)度可控。但是會(huì)有內(nèi)存疊加的問(wèn)題。 sprintf是格式化函數(shù)。將一段數(shù)據(jù)通過(guò)特定的格式,格式化到一個(gè)字符串緩沖區(qū)中去。sprintf格式化的函數(shù)的長(zhǎng)度不可控,有可能格式化后的字符串會(huì)超出緩沖區(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是一個(gè)屬性訪問(wèn)聲明,擴(kuò)號(hào)內(nèi)支持以下幾個(gè)屬性: 1,getter=getterName,setter=setterName,設(shè)置setter與getter的方法名 2,readwrite,readonly,設(shè)置可供訪問(wèn)級(jí)別 2,assign,setter方法直接賦值,不進(jìn)行任何retain操作,為了解決原類型與環(huán)循引用問(wèn)題 3,retain,setter方法對(duì)參數(shù)進(jìn)行release舊值再retain新值,所有實(shí)現(xiàn)都是這個(gè)順序(CC上有相關(guān)資料) 4,copy,setter方法進(jìn)行Copy操作,與retain處理流程一樣,先舊值
65、release,再Copy出新的對(duì)象,retainCount為1。這是為了減少對(duì)上下文的依賴而引入的機(jī)制。 copy是在你不希望a和b共享一塊內(nèi)存時(shí)會(huì)使用到。a和b各自有自己的內(nèi)存。5,nonatomic,非原子性訪問(wèn),不加同步,多線程并發(fā)訪問(wèn)會(huì)提高性能。注意,如果不加此屬性,則默認(rèn)是兩個(gè)訪問(wèn)方法都為原子型事務(wù)訪問(wèn)。鎖被加到所屬對(duì)象實(shí)例級(jí)(我是這么理解的.)。atomic和nonatomic用來(lái)決定編譯器生成的getter和setter是否為原子操作。在多線程環(huán)境下,原子操作是必要的,否則有可能引起錯(cuò) 誤的結(jié)果。加了atomic,setter函數(shù)會(huì)變成下面這樣:16什么時(shí)候用dele
66、gate,什么時(shí)候用Notification?答:delegate針對(duì)one-to-one關(guān)系,并且reciever可以返回值 給sender,notification 可以針對(duì)one-to-one/many/none,reciever無(wú)法返回值給sender.所以,delegate用于sender希望接受到 reciever的某個(gè)功能反饋值,notification用于通知多個(gè)object某個(gè)事件。 17什么是KVC和KVO?答:KVC(Key-Value-Coding)內(nèi)部的實(shí)現(xiàn):一個(gè)對(duì)象在調(diào)用setValue的時(shí)候,(1)首先根據(jù)方法名找到運(yùn)行方法
67、的時(shí)候所需要的環(huán)境參數(shù)。(2)他會(huì)從自己isa指針結(jié)合環(huán)境參數(shù),找到具體的方法實(shí)現(xiàn)的接口。(3)再直接查找得來(lái)的具體的方法實(shí)現(xiàn)。KVO(Key-Value- Observing):當(dāng)觀察者為一個(gè)對(duì)象的屬性進(jìn)行了注冊(cè),被觀察對(duì)象的isa指針被修改的時(shí)候,isa指針就會(huì)指向一個(gè)中間類,而不是真實(shí)的類。所以 isa指針其實(shí)不需要指向?qū)嵗龑?duì)象真實(shí)的類。所以我們的程序最好不要依賴于isa指針。在調(diào)用類的方法的時(shí)候,最好要明確對(duì)象實(shí)例的類名18ViewController 的 loadView, viewDidLoad, viewDidUnload 分別是在什么時(shí)候
68、調(diào)用的?在自定義ViewController的時(shí)候這幾個(gè)函數(shù)里面應(yīng)該做什么工作?答:viewDidLoad在view 從nib文件初始化時(shí)調(diào)用,loadView在controller的view為nil時(shí)調(diào)用。此方法在編程實(shí)現(xiàn)view時(shí)調(diào)用,view 控制器默認(rèn)會(huì)注冊(cè)memory warning notification,當(dāng)view controller的任何view 沒有用的時(shí)候,viewDidUnload會(huì)被調(diào)用,在這里實(shí)現(xiàn)將retain 的view release,如果是retain的IBOutlet view 屬性則不要在這里release,IBOutlet會(huì)負(fù)責(zé)release 。19"NSMutableString *"這個(gè)數(shù)據(jù)
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年庫(kù)房轉(zhuǎn)租合同轉(zhuǎn)租條件、轉(zhuǎn)租手續(xù)及租金處理分析
- 2024年企業(yè)內(nèi)部審計(jì)保密協(xié)議
- 2024年度企業(yè)社會(huì)責(zé)任報(bào)告合同
- 2024年度住宅小區(qū)木門安裝工程合同
- 2024年度許可使用合同(商標(biāo))
- 腰椎ct課件教學(xué)課件
- 2024北京技術(shù)合同
- 2024年大數(shù)據(jù)使用協(xié)議:數(shù)據(jù)收集、分析和應(yīng)用的具體規(guī)定
- 液體密度課件教學(xué)課件
- 輿論學(xué)課件教學(xué)
- 2024-2025學(xué)年二年級(jí)上學(xué)期數(shù)學(xué)期中模擬試卷(蘇教版)(含答案解析)
- 入團(tuán)志愿書(2016版本)(可編輯打印標(biāo)準(zhǔn)A4) (1)
- 浙江省公路山嶺隧道機(jī)械化裝備應(yīng)用指導(dǎo)手冊(cè)
- (完整word版)拼音練習(xí)jqx和ü、üe的相拼
- 醫(yī)療質(zhì)量檢查分析、總結(jié)、反饋5篇
- 桅桿工藝技術(shù)及施工要求
- (完整版)六年級(jí)下冊(cè)體育教學(xué)計(jì)劃與教案
- 北京地鐵受電弓的維護(hù)與故障檢修-畢業(yè)設(shè)計(jì)說(shuō)明書
- 幼兒園教育和家庭教育的有效結(jié)合研究
- 集團(tuán)公司兩金管理評(píng)價(jià)辦法
- 電影的聲音分析PPT課件
評(píng)論
0/150
提交評(píng)論