1晕拆、id 聲明的對(duì)象有什么特性绘梦?
id
聲明的對(duì)象具有運(yùn)行時(shí)的特性,即可以指向任意類型的Objective-C對(duì)象(與C中的void*
萬(wàn)能指針相似)涯竟。
2赡鲜、Object-C的類可以多重繼承么? 可以實(shí)現(xiàn)多個(gè)接口么?
Object-C的類不可以多重繼承;可以實(shí)現(xiàn)多個(gè)接口庐船,通過(guò)實(shí)現(xiàn)多個(gè)接口可以完成C++的多重繼承银酬;
3、category是什么? 重寫一個(gè)類的方式用繼承好還是分類好? 為什么?
Category是類別筐钟,一般情況用分類好; 用Category去重寫類的方法揩瞪,僅對(duì)本Category有效,不會(huì)影響到其他類與原有類的關(guān)系篓冲。
4李破、#import跟#include有什么區(qū)別,@class呢? #import<>跟#import“”有什么區(qū)別?
#import
是Objective-C導(dǎo)入頭文件的關(guān)鍵字宠哄,#include
是C/C++導(dǎo)入頭文件的關(guān)鍵字,使用#import頭文件會(huì)自動(dòng)只導(dǎo)入一次,不會(huì)重復(fù)導(dǎo)入嗤攻,相當(dāng)于#include和#pragma once毛嫉;@class告訴編譯器某個(gè)類的聲明爸舒,當(dāng)執(zhí)行時(shí)腕让,才去查看類的實(shí)現(xiàn)文件,可以解決頭文件的相互包含舀透;#import<>
用來(lái)包含系統(tǒng)的頭文件恶耽,#import“”
用來(lái)包含用戶頭文件密任。
5、對(duì)于語(yǔ)句NSString *obj = [[NSData alloc] init]; obj在編譯時(shí)和運(yùn)行時(shí)分別是什么類型的對(duì)象?
編譯時(shí)是NSString的類型偷俭;運(yùn)行時(shí)是NSData類型的對(duì)象
6浪讳、什么情況下使用關(guān)鍵字weak和assign,兩者有何不同?
他們常用在基本類型屬性涌萤,比如BOOL淹遵,int等,還有就是delegate负溪。
在使用delegate時(shí)透揣,需要注意,非ARC時(shí)是使用assign川抡,但到了ARC時(shí)代辐真,都建議使用weak,這樣更安全崖堤。
不管是在非ARC還是ARC侍咱,使用assign時(shí),都需要注意釋放
assign指針賦值, 不對(duì)引用計(jì)數(shù)操作, 使用之后如果沒(méi)有置為nil, 可能就會(huì)產(chǎn)生野指針; 而weak一旦不進(jìn)行使用后, 永遠(yuǎn)不會(huì)使用了, 就不會(huì)產(chǎn)生野指針密幔。
assigin可以用于非OC對(duì)象楔脯,但是weak必須用于OC對(duì)象。
7胯甩、KVO的實(shí)現(xiàn)原理?
- KVO是基于runtime機(jī)制實(shí)現(xiàn)的
- 當(dāng)某個(gè)類的屬性對(duì)象第一次被觀察時(shí)昧廷,系統(tǒng)就會(huì)在運(yùn)行期動(dòng)態(tài)地創(chuàng)建該類的一個(gè)派生類,在這個(gè)派生類中重寫基類中任何被觀察屬性的setter 方法偎箫。派生類在被重寫的setter方法內(nèi)實(shí)現(xiàn)真正的通知機(jī)制
- 如果原類為Person木柬,那么生成的派生類名為NSKVONotifying_Person
- 每個(gè)類對(duì)象中都有一個(gè)isa指針指向當(dāng)前類,當(dāng)一個(gè)類對(duì)象的第一次被觀察淹办,那么系統(tǒng)會(huì)偷偷將isa指針指向動(dòng)態(tài)生成的派生類弄诲,從而在給被監(jiān)控屬性賦值時(shí)執(zhí)行的是派生類的setter方法
- 鍵值觀察通知依賴于NSObject的兩個(gè)方法:willChangeValueForKey:和didChangeValueForKey:;在一個(gè)被觀察屬性發(fā)生改變之前;willChangeValueForKey:一定會(huì)被調(diào)用齐遵,這就會(huì)記錄舊的值寂玲。而當(dāng)改變發(fā)生后,didChangeValueForKey:會(huì)被調(diào)用梗摇,繼而observeValueForKey:ofObject:change:context:也會(huì)被調(diào)用拓哟。
- 補(bǔ)充:KVO的這套實(shí)現(xiàn)機(jī)制中蘋果還偷偷重寫了class方法,讓我們誤認(rèn)為還是使用的當(dāng)前類伶授,從而達(dá)到隱藏生成的派生類
參考資料1
參考資料2
8断序、loadView方法什么時(shí)候調(diào)用?一般在此方法里面做什么操作糜烹?
當(dāng)控制器ViewController要展示的view為nil的時(shí)候調(diào)用該方法违诗,ViewController會(huì)自動(dòng)調(diào)用loadView方法來(lái)初始化一個(gè)UIView并賦值給view屬性
9、請(qǐng)描述一下SDWebImage內(nèi)部實(shí)現(xiàn)的原理
首先介紹一下 這個(gè)庫(kù)的作用
1疮蹦、UIImageView (WebCache)類別诸迟,入口封裝,實(shí)現(xiàn)讀取圖片完成后的回調(diào)
2愕乎、SDWebImageManager阵苇,對(duì)圖片進(jìn)行管理的中轉(zhuǎn)站,記錄那些圖片正在讀取感论。
向下層讀取Cache(調(diào)用SDImageCache)绅项,或者向網(wǎng)絡(luò)讀取對(duì)象(調(diào)用SDWebImageDownloader)。
實(shí)現(xiàn)SDImageCache和SDWebImageDownloader的回調(diào)比肄。
3快耿、SDImageCache,根據(jù)URL的MD5摘要對(duì)圖片進(jìn)行存儲(chǔ)和讀确技ā(實(shí)現(xiàn)存在內(nèi)存中或者存在硬盤上兩種實(shí)現(xiàn))
實(shí)現(xiàn)圖片和內(nèi)存清理工作掀亥。
4、SDWebImageDownloader示括,根據(jù)URL向網(wǎng)絡(luò)讀取數(shù)據(jù)(實(shí)現(xiàn)部分讀取和全部讀取后再通知回調(diào)兩種方式)
SDWebImage實(shí)現(xiàn)原理
1.sd_setImageWithURL:url 先把默認(rèn)圖片顯示出來(lái)
2.SDWebImageManager-downloadImageWithURL 從內(nèi)存圖片緩存中查找是否已經(jīng)有圖片queryDiskCacheForKey
3.imageFromMemoryCacheForKey 先從緩存中查找
4.如果有則展示圖片
5.如果緩存中沒(méi)有 生成NSInvocationOperation 添加到隊(duì)列queryDiskCacheForKey
從硬盤查找是否已經(jīng)有圖片
6.從硬盤緩存目錄讀取文件 這一步是在NSOperator 進(jìn)行操作
回到主線程進(jìn)行結(jié)果回調(diào) notifyDelegate
7.如果讀取到了圖片 將圖片添加到內(nèi)存緩存中 SDImageCacheDelegate回調(diào)imageCache:didFindImage:forKey:userinfo:
8.如果從硬盤目錄中讀取不到圖片 說(shuō)明圖片不存在 需要下載圖片
imageCache:didNotFindImage:forKey:userinfo:
9.重新生成一個(gè)下載器 SDWebImageDownloader開(kāi)始下載圖片
10.圖片下載由NSURLConnection來(lái)做 實(shí)現(xiàn)相關(guān)delegate 來(lái)判斷圖片下載狀態(tài)
//下面是下載過(guò)程
11.connection:didReceiveData:中利用ImageIO作了按圖片進(jìn)度加載效果
12.connectionDidFinishLoading:數(shù)據(jù)下載完成后交給SDWebImageDecoder做圖片的解碼處理
13.圖片解碼處理在一個(gè)NSOperationQueue完成不會(huì)拖慢主線程UI
14.在主線程notifiyDelegateOnMainThreadWithInfo 宣告解碼完成
imageDecoder:didFinishDecodingImage:userInfo回調(diào)給SDWebImageDownloader
15.imageDownloder:didFinishWithImage:回調(diào)給SDWebImageManage 告知圖片下載完成
16.通知所有的downloadDelegates下載完成,回調(diào)給需要的地方展示圖片
17.將圖片保存到SDImageCache中痢畜,內(nèi)存緩存和硬盤緩存同時(shí)保存
寫文件到硬盤 可以單獨(dú)在NSInvocationOperation中完成 避免拖慢主線程
18.SDImageCache 在初始化的時(shí)候會(huì)注釋一些消息通知垛膝,在內(nèi)存警告或退到后臺(tái)的時(shí)候清理內(nèi)存圖片緩存,應(yīng)用結(jié)束的時(shí)候清理過(guò)期的圖片
19.SDWebImage 也提供了UIButton+WebCache 和MKAnnotioinView+WebCache方便使用
20.SDWebImagePrefetcher可以預(yù)先下載圖片 方便以后使用
10丁稀、線程間怎么通信?
線程間通信:
在1個(gè)進(jìn)程中吼拥,線程往往不是孤立存在的,多個(gè)線程之間需要經(jīng)常進(jìn)行通信
線程間通信的體現(xiàn):
1個(gè)線程傳遞數(shù)據(jù)給另1個(gè)線程
在1個(gè)線程中執(zhí)行完特定任務(wù)后线衫,轉(zhuǎn)到另1個(gè)線程繼續(xù)執(zhí)行任務(wù)
線程間通信常用方法:
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 1.耗時(shí)操作處理
dispatch_async(dispatch_get_main_queue(), ^{
// 2.回到主線程更新頁(yè)面和數(shù)據(jù)
});
});
11凿可、iOS中的數(shù)據(jù)持久化方案有哪些?
plist文件(屬性列表)、preference(偏好設(shè)置NSUserDefaults枯跑,用于存儲(chǔ)配置信息)惨驶、NSKeyedArchiver(歸檔)、SQList敛助、CoreData
12粗卜、描述一下iOS SDK中如何實(shí)現(xiàn)MVC的開(kāi)發(fā)模式
MVC是模型、視圖纳击、控制器開(kāi)發(fā)模式续扔,對(duì)于iOS SDK,所有的View都是視圖層的焕数,它應(yīng)該獨(dú)立于模型層纱昧,由視圖器來(lái)控制。所有的用戶數(shù)據(jù)都是模型層堡赔,它應(yīng)該獨(dú)立于視圖识脆。所有的ViewController都是視圖器,由它負(fù)責(zé)控制視圖加匈,訪問(wèn)模型數(shù)據(jù)存璃。
13、請(qǐng)用簡(jiǎn)單的代碼展示@protocol的定義及實(shí)現(xiàn).
#warning代理第一步:聲明協(xié)議
@protocol MarryMe
- (void)makeMoney;
@end
#warning代理第二步:聲明代理
@property(nonatomic, weak) id myDeleget;
.m文件中
#warning代理第三步:代理人執(zhí)行協(xié)議方法
[self.myDeleget makeMoney];
代理人.m文件中
#warning代理第四步:簽訂協(xié)議
@interface Boy : NSObject
Girl *girl = [[Girl alloc] init];
#warning代理第五步:成為代理人
girl.myDeleget = self;
[girl getMessage:message];
#warning協(xié)議代理第六步:實(shí)現(xiàn)協(xié)議方法
- (void)makeMoney {
NSLog(@"=");
}
14雕拼、iOS中delegate代理對(duì)象使用weak和assign哪個(gè)更好纵东?
使用
assign
聲明一個(gè)delegate,那么即便delegate指向的對(duì)象銷毀了啥寇,delegate中依然會(huì)保存之前對(duì)象的地址, 即delegate成為了一個(gè)野指針偎球;而使用weak
,則不會(huì)有上述問(wèn)題辑甜,當(dāng)delegate指向的對(duì)象銷毀后衰絮,delegate = nil。所以建議使用weak磷醋。資料
15猫牡、解釋一下iOS內(nèi)存管理機(jī)制和規(guī)則
iOS內(nèi)存管理機(jī)制的原理是
引用計(jì)數(shù)
,引用計(jì)數(shù)
是一個(gè)簡(jiǎn)單而有效的管理對(duì)象生命周期的方式邓线。當(dāng)我們創(chuàng)建一個(gè)新對(duì)象的時(shí)候淌友,他的引用計(jì)數(shù)為1,當(dāng)有一個(gè)新的指針指向這個(gè)對(duì)象骇陈,我們將其引用計(jì)數(shù)加1震庭,當(dāng)某個(gè)指針不再指向這個(gè)對(duì)象時(shí),我們將其引用計(jì)數(shù)減1你雌,當(dāng)對(duì)象的引用計(jì)數(shù)為0時(shí)器联,說(shuō)明這個(gè)對(duì)象不再被任何指針指向了,這個(gè)時(shí)候我們就可以將對(duì)象銷毀,回收內(nèi)存拨拓。
參考資料1
參考資料2
參考資料3
16肴颊、define 和 const常量有什么區(qū)別?
const
為常量值千元,define
為字符串替換苫昌。
-
const
在編譯階段使用;define
在預(yù)編譯階段使用幸海。 -
const
有數(shù)據(jù)類型祟身,做安全檢查;define
無(wú)類型物独,不做安全檢查袜硫。 -
const
可以調(diào)試;define
不能調(diào)試挡篓。 -
const
占用一份內(nèi)存婉陷;define
不占用內(nèi)存,但是會(huì)多處進(jìn)行字符串替換
參考資料
17官研、iOS如何避免內(nèi)測(cè)泄漏秽澳?怎么調(diào)試?
18戏羽、runloop是什么担神?它和線程有什么關(guān)系?RunLoop內(nèi)部是怎么實(shí)現(xiàn)的始花?
Run Loop是一讓線程能隨時(shí)處理事件但不退出的機(jī)制;
- RunLoop 的作用就是來(lái)管理線程的妄讯,當(dāng)線程的 RunLoop 開(kāi)啟后,線程就會(huì)在執(zhí)行完任務(wù)后酷宵,處于休眠狀態(tài)亥贸,隨時(shí)等待接受新的任務(wù),而不是退出;
- 只有主線程的RunLoop是默認(rèn)開(kāi)啟的浇垦,所以程序在開(kāi)啟后炕置,會(huì)一直運(yùn)行,不會(huì)退出男韧。其他線程的RunLoop 如果需要開(kāi)啟朴摊,就手動(dòng)開(kāi)啟;
- //猜想runloop內(nèi)部是如何實(shí)現(xiàn)的?
1煌抒、有一個(gè)判斷循環(huán)的條件仍劈,滿足條件厕倍,就一直循環(huán)
2寡壮、線程得到喚醒事件被喚醒,事件處理完畢以后,回到睡眠狀態(tài)况既,等待下次喚醒
參考資料
19这溅、常用的設(shè)計(jì)模式有哪些?說(shuō)兩個(gè)iOS開(kāi)發(fā)中常見(jiàn)的棒仍。
20悲靴、說(shuō)說(shuō)UIView觸摸事件的傳遞;不能接受觸摸事件的原因可能有哪些莫其?如何找出最合適處理事件的控件癞尚?
21、copy和strong關(guān)鍵字的區(qū)別乱陡?
strong
與copy
都會(huì)使引用計(jì)數(shù)加1浇揩,但strong
是兩個(gè)指針指向同一個(gè)內(nèi)存地址,copy
會(huì)在內(nèi)存里拷貝一份對(duì)象憨颠,兩個(gè)指針指向不同的內(nèi)存地址
22胳徽、如何高性能的給UIImageView加個(gè)圓角?
23爽彤、UIView和CALayer的關(guān)系养盗?
寫在最后
如有錯(cuò)誤,請(qǐng)指教适篙!