必問
1.下載一個(gè)面試者做過的應(yīng)用设褐,找一個(gè)面試者做過的頁面分析下頁面結(jié)構(gòu)、約束或者 frame 布局的連法和計(jì)算方法丸卷;
2.說說 UITableView 常用的幾個(gè) delegate 和 data source 代理方法挺举,動(dòng)態(tài) Cell 高度計(jì)算什么的;
3.接下來辨萍,在手機(jī)里隨便找一個(gè) App 的頁面棋恼,讓面試者當(dāng)場(chǎng)說說如果是他寫應(yīng)該用哪些 UI 組件和布局方式等。
4.你實(shí)現(xiàn)過一個(gè)框架或者庫(kù)以供別人使用么锈玉?如果有爪飘,請(qǐng)談一談構(gòu)建框架或者庫(kù)時(shí)候的經(jīng)驗(yàn);如果沒有拉背,請(qǐng)?jiān)O(shè)想和設(shè)計(jì)框架的public的API师崎,并指出大概需要如何做、需要注意一些什么方面椅棺,來使別人容易地使用你的框架
答:抽象和封裝犁罩,方便使用齐蔽。首先是對(duì)問題有充分的了解,比如構(gòu)建一 個(gè)文件解壓壓縮框架床估,從使用者的角度出發(fā)含滴,只需關(guān)注發(fā)送給框架一個(gè) 解壓請(qǐng)求,框架完成復(fù)雜文件的解壓操作丐巫,并且在適當(dāng)?shù)臅r(shí)候通知給是 哦難過者谈况,如解壓完成、解壓出錯(cuò)等递胧。在框架內(nèi)部去構(gòu)建對(duì)象的關(guān)系碑韵, 通過抽象讓其更為健壯、便于更改谓着。其次是API的說明文檔泼诱。
5.架構(gòu)上 MVC 還是 MVVM 還是 MVP 神馬的到是可以聊聊各自的見解
上架經(jīng)驗(yàn),被拒絕的原因赊锚,有哪些坑治筒,什么開發(fā)者賬號(hào),多少錢舷蒲,用什么布局頁面耸袜。
以上問完了,基本對(duì)面試者的實(shí)力實(shí)力牲平,表達(dá)能力都了解一點(diǎn)堤框,下面的問題再挑選一些詢問,面試就搞定了
私人問題:
是否有女朋友纵柿;女朋友是不是在本地工作蜈抓;薪資要求;日常加班是否有時(shí)間昂儒;居住地離公司多遠(yuǎn)沟使;是否需要配置蘋果電腦;
觀察面試者脾氣渊跋,是否認(rèn)真端正腊嗡,是否強(qiáng)硬爭(zhēng)辯玫鸟,是否禮貌秒紧;
孩子年齡小需要照顧,沒多少時(shí)間
面試者年齡大盆赤,售后服務(wù)不行蒿囤,生活穩(wěn)定怕風(fēng)險(xiǎn)客们!
基礎(chǔ)
1.@property后面可以有哪些修飾符
一類是表示原子性(也就是線程安全)的,有atomic和nonatomic,默認(rèn)是atomic底挫,acomic也就是線程安全嗽桩,但是我們一般都用的nonatomic,因?yàn)閍tomic的線程安全開銷太大凄敢,影響性能,即使需要保證線程安全湿痢,我們也可以通過自己的代碼控制涝缝,而不用atomic。
一類是表示引用計(jì)數(shù)的譬重,有assign(iOS5以前用unsafe_unretained),strong,weak,copy拒逮。
assign: assign用于非指針變量,一般用于基礎(chǔ)類型和C數(shù)據(jù)類型臀规,這些類型不是對(duì)象滩援,統(tǒng)一由系統(tǒng)棧進(jìn)行內(nèi)存管理。
weak:對(duì)對(duì)象的弱引用塔嬉,不增加對(duì)象的引用計(jì)數(shù)玩徊,也不持有對(duì)象,當(dāng)對(duì)象消失后指針自動(dòng)指向nil谨究,所以這里也就防止了野指針的存在恩袱。
strong:對(duì)對(duì)象的強(qiáng)引用,會(huì)增加對(duì)象的引用計(jì)數(shù)胶哲,如果指向了一個(gè)空對(duì)象畔塔,會(huì)造成野指針,平常我們用得最多的應(yīng)該也是strong了鸯屿。
copy:建立一個(gè)引用計(jì)數(shù)為1的新對(duì)象澈吨,賦值時(shí)對(duì)傳入值進(jìn)行一份拷貝,所以使用copy關(guān)鍵字的時(shí)候寄摆,你將一個(gè)對(duì)象復(fù)制給該屬性谅辣,該屬性并不會(huì)持有那個(gè)對(duì)象,而是會(huì)創(chuàng)建一個(gè)新對(duì)象冰肴,并將那個(gè)對(duì)象的值拷貝給它屈藐。而使用copy關(guān)鍵字的對(duì)象必須要實(shí)現(xiàn)NSCopying協(xié)議。
unsafe_unretained:跟 weak 類似熙尉,聲明一個(gè)弱引用联逻,但是當(dāng)引用計(jì)數(shù)為 0 時(shí),變量不會(huì)自動(dòng)設(shè)置為 nil检痰,現(xiàn)在基本都用weak了包归。
一類是表示讀寫權(quán)限的,默認(rèn)是readwrite(可讀可寫)铅歼,還有就是readonly公壤,當(dāng)你希望暴露出來的屬性不能被外界修改時(shí)就需要申明為readonly换可。
2.這個(gè)寫法會(huì)出什么問題: @property (copy) NSMutableArray *array;
一個(gè)屬性如果標(biāo)記了copy,當(dāng)你調(diào)用其setter方法時(shí)厦幅,他會(huì)建立一個(gè)索引計(jì)數(shù)為1的對(duì)象沾鳄,然后釋放舊對(duì)象。
其實(shí)就是一個(gè)NSArray對(duì)其做增刪改查的時(shí)候都會(huì)找不到該方法确憨,程序崩潰译荞。
3.什么情況使用 weak 關(guān)鍵字,相比 assign 有什么不同休弃?
1.在ARC模式下吞歼,在有可能出現(xiàn)循環(huán)引用時(shí),讓其一端使用weak修飾塔猾。例如:delegate(代理)屬性
2.自身已經(jīng)對(duì)它強(qiáng)引用一次了篙骡,沒有必再?gòu)?qiáng)引用一次使用weak解決。例如:自定義IBOutlet控件屬性
兩者區(qū)別:
1.weak只能用于修飾對(duì)象類型丈甸,基本數(shù)據(jù)類型不能使用
2.assign修飾對(duì)象和基本數(shù)據(jù)類型都可以,但是只是簡(jiǎn)單地進(jìn)行賦值操作而已
注意:assign修飾的對(duì)象(一般編譯的時(shí)候會(huì)產(chǎn)生警告:Assigning retained object to unsafe property; object will be released after assignment)在釋放之后糯俗,指針的地址還是存在的,也就是說指針并沒有被置為nil老虫,造成野指針叶骨。對(duì)象一般分配在堆上的某塊內(nèi)存,如果在后續(xù)的內(nèi)存分配中祈匙,剛好分到了這塊地址忽刽,程序就會(huì)崩潰掉。
那為什么可以用assign修飾基本數(shù)據(jù)類型夺欲?因?yàn)榛A(chǔ)數(shù)據(jù)類型一般分配在棧上跪帝,棧的內(nèi)存會(huì)由系統(tǒng)自己自動(dòng)處理,不會(huì)造成野指針些阅。
weak修飾的對(duì)象在釋放之后伞剑,指針地址會(huì)被置為nil。所以現(xiàn)在一般弱引用就是用weak市埋。
4.架構(gòu)上 MVC 還是 MVVM 還是 MVP 神馬的到是可以聊聊各自的見解黎泣,
5. 常見的Objective-C 的數(shù)據(jù)類型有那些,和C的基本數(shù)據(jù)類型有什么區(qū)別缤谎?如:NSInteger和int
Objective-C的數(shù)據(jù)類型有NSString抒倚,NSNumber,NSArray坷澡,NSMutableArray托呕,NSData等等,這些都是class,創(chuàng)建后便是對(duì)象项郊,而C語言的基本數(shù)據(jù)類型int馅扣,只是一定字節(jié)的內(nèi)存空間,用于存放數(shù)值;NSInteger是基本數(shù)據(jù)類型着降,并不是NSNumber的子類差油,當(dāng)然也不是NSObject的子類。NSInteger是基本數(shù)據(jù)類型Int或者Long的別名(NSInteger的定義typedeflongNSInteger)任洞,它的區(qū)別在于厌殉,NSInteger會(huì)根據(jù)系統(tǒng)是32位還是64位來決定是本身是int還是long。
6.ViewController生命周期
按照?qǐng)?zhí)行順序排列:
1. initWithCoder:通過nib文件初始化時(shí)觸發(fā)侈咕。
2. awakeFromNib:nib文件被加載的時(shí)候,會(huì)發(fā)生一個(gè)awakeFromNib的消息到nib文件中的每個(gè)對(duì)象器紧。
3. loadView:開始加載視圖控制器自帶的view耀销。
4. viewDidLoad:視圖控制器的view被加載完成。
5. viewWillAppear:視圖控制器的view將要顯示在window上铲汪。
6. updateViewConstraints:視圖控制器的view開始更新AutoLayout約束熊尉。
7. viewWillLayoutSubviews:視圖控制器的view將要更新內(nèi)容視圖的位置。
8. viewDidLayoutSubviews:視圖控制器的view已經(jīng)更新視圖的位置掌腰。
9. viewDidAppear:視圖控制器的view已經(jīng)展示到window上狰住。
10.viewWillDisappear:視圖控制器的view將要從window上消失。
11.viewDidDisappear:視圖控制器的view已經(jīng)從window上消失齿梁。
中階
1.用@property聲明的NSString(或NSArray催植,NSDictionary)經(jīng)常使用copy關(guān)鍵字,為什么勺择?如果改用strong關(guān)鍵字创南,可能造成什么問題?
1省核、因?yàn)楦割愔羔樋梢灾赶蜃宇悓?duì)象,使用copy的目的是為了讓本對(duì)象的
屬性不受外界影響,使用copy無論給我傳入是一個(gè)可變對(duì)象還是不可對(duì)
象,我本身持有的就是一個(gè)不可變的副本.
2稿辙、如果我們使用是strong,那么這個(gè)屬性就有可能指向一個(gè)可變對(duì)象,如
果這個(gè)可變對(duì)象在外部被修改了,那么會(huì)影響該屬性.
copy此特質(zhì)所表達(dá)的所屬關(guān)系與strong類似。然而設(shè)置方法并不保留新值气忠,而是將其“拷貝” (copy)邻储。
當(dāng)屬性類型為NSString時(shí),經(jīng)常用此特質(zhì)來保護(hù)其封裝性旧噪,因?yàn)閭鬟f給設(shè)置方法的新值有可能指向一個(gè)NSMutableString類的實(shí)例吨娜。
這個(gè)類是NSString的子類,表示一種可修改其值的字符串舌菜,此時(shí)若是不拷貝字符串萌壳,那么設(shè)置完屬性之后,字符串的值就可能會(huì)在對(duì)象不知情的情況下遭人更改。
所以袱瓮,這時(shí)就要拷貝一份“不可變” (immutable)的字符串缤骨,確保對(duì)象中的字符串值不會(huì)無意間變動(dòng)。只要實(shí)現(xiàn)屬性所用的對(duì)象是“可變的”
(mutable)尺借,就應(yīng)該在設(shè)置新屬性值時(shí)拷貝一份绊起。
2.簡(jiǎn)單介紹一下設(shè)計(jì)模式:
1) MVC模式:Model View Control,把模型 視圖 控制器 層進(jìn)行解耦合編寫燎斩。2). MVVM模式:Model View ViewModel 把模型 視圖 業(yè)務(wù)邏輯 層進(jìn)行解耦和編寫虱歪。
3). 單例模式:通過static關(guān)鍵詞,聲明全局變量栅表。在整個(gè)進(jìn)程運(yùn)行期間只會(huì)被賦值一次笋鄙。
4). 觀察者模式:KVO是典型的通知模式,觀察某個(gè)屬性的狀態(tài)怪瓶,狀態(tài)發(fā)生變化時(shí)通知觀察者萧落。
5). 委托模式:代理+協(xié)議的組合。實(shí)現(xiàn)1對(duì)1的反向傳值操作洗贰。
3.Category(類別)找岖、Extension(擴(kuò)展)和繼承的區(qū)別
區(qū)別:
分類有名字,類擴(kuò)展沒有分類名字敛滋,是一種特殊的分類许布。
分類只能擴(kuò)展方法(屬性僅僅是聲明,并沒真正實(shí)現(xiàn))绎晃,類擴(kuò)展可以擴(kuò)展屬性蜜唾、成員變量和方法。
繼承可以增加庶艾,修改或者刪除方法灵妨,并且可以增加屬性。
4.什么是KVO 和KVC落竹?
1). KVC(Key-Value-Coding):鍵值編碼 是一種通過字符串間接訪問對(duì)象的方式(即給屬性賦值)
舉例說明:
stu.name = @"張三" // 點(diǎn)語法給屬性賦值
[stu setValue:@"張三" forKey:@"name"]; // 通過字符串使用KVC方式給屬性賦值
stu1.nameLabel.text = @"張三";
[stu1 setValue:@"張三" forKeyPath:@"nameLabel.text"]; // 跨層賦值
2). KVO(key-Value-Observing):鍵值觀察機(jī)制 他提供了觀察某一屬性變化的方法泌霍,極大的簡(jiǎn)化了代碼。
KVO只能被KVC觸發(fā)述召,包括使用setValue:forKey:方法和點(diǎn)語法朱转。
// 通過下方方法為屬性添加KVO觀察
- (void)addObserver:(NSObject *)observer
forKeyPath:(NSString *)keyPath
options:(NSKeyValueObservingOptions)options
context:(nullable void *)context;
// 當(dāng)被觀察的屬性發(fā)送變化時(shí),會(huì)自動(dòng)觸發(fā)下方方法
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context{}
KVC 和 KVO 的 keyPath 可以是屬性积暖、實(shí)例變量藤为、成員變量。
4.block的注意點(diǎn)
1). 在block內(nèi)部使用外部指針且會(huì)造成循環(huán)引用情況下夺刑,需要用__week修飾外部指針: __weaktypeof(self) weakSelf = self;
2). 在block內(nèi)部如果調(diào)用了延時(shí)函數(shù)還使用弱指針會(huì)取不到該指針缅疟,因?yàn)橐呀?jīng)被銷毀了分别,需要在block內(nèi)部再將弱指針重新強(qiáng)引用一下。 __strongtypeof(self) strongSelf = weakSelf;
3). 如果需要在block內(nèi)部改變外部棧區(qū)變量的話存淫,需要在用__block修飾外部變量
5.什么是 TCP / UDP ?
TCP:傳輸控制協(xié)議耘斩。
UDP:用戶數(shù)據(jù)協(xié)議。
TCP 是面向連接的桅咆,建立連接需要經(jīng)歷三次握手括授,是可靠的傳輸層協(xié)議。
UDP 是面向無連接的岩饼,數(shù)據(jù)傳輸是不可靠的荚虚,它只管發(fā),不管收不收得到籍茧。
簡(jiǎn)單的說版述,TCP注重?cái)?shù)據(jù)安全,而UDP數(shù)據(jù)傳輸快點(diǎn)寞冯,但安全性一般院水。
6.HTTP協(xié)議中 POST 方法和 GET 方法有那些區(qū)別?
- GET用于向服務(wù)器請(qǐng)求數(shù)據(jù),POST用于提交數(shù)據(jù)
- GET請(qǐng)求简十,請(qǐng)求參數(shù)拼接形式暴露在地址欄,而POST請(qǐng)求參數(shù)則放在請(qǐng)求體里面撬腾,因此GET請(qǐng)求不適合用于驗(yàn)證密碼等操作
- GET請(qǐng)求的URL有長(zhǎng)度限制螟蝙,POST請(qǐng)求不會(huì)有長(zhǎng)度限制
7.請(qǐng)簡(jiǎn)單的介紹下APNS發(fā)送系統(tǒng)消息的機(jī)制
APNS優(yōu)勢(shì):杜絕了類似安卓那種為了接受通知不停在后臺(tái)喚醒程序保持長(zhǎng)連接的行為,由iOS系統(tǒng)和APNS進(jìn)行長(zhǎng)連接替代民傻。 APNS的原理:
1). 應(yīng)用在通知中心注冊(cè)胰默,由iOS系統(tǒng)向APNS請(qǐng)求返回設(shè)備令牌(device Token)
2). 應(yīng)用程序接收到設(shè)備令牌并發(fā)送給自己的后臺(tái)服務(wù)器
3). 服務(wù)器把要推送的內(nèi)容和設(shè)備發(fā)送給APNS
4). APNS根據(jù)設(shè)備令牌找到設(shè)備,再由iOS根據(jù)APPID把推送內(nèi)容展示
8.述下SDWebImage里面給UIImageView加載圖片的邏輯
SDWebImage 中為 UIImageView提供了一個(gè)分類UIImageView+WebCache.h, 這個(gè)分類中有一個(gè)最常用的接口sd_setImageWithURL:placeholderImage:漓踢,會(huì)在真實(shí)圖片出現(xiàn)前會(huì)先顯示占位圖片牵署,當(dāng)真實(shí)圖片被加載出來后再替換占位圖片。
加載圖片的過程大致如下:
1.首先會(huì)在 SDWebImageCache 中尋找圖片是否有對(duì)應(yīng)的緩存, 它會(huì)以u(píng)rl 作為數(shù)據(jù)的索引先在內(nèi)存中尋找是否有對(duì)應(yīng)的緩存
2.如果緩存未找到就會(huì)利用通過MD5處理過的key來繼續(xù)在磁盤中查詢對(duì)應(yīng)的數(shù)據(jù), 如果找到了, 就會(huì)把磁盤中的數(shù)據(jù)加載到內(nèi)存中喧半,并將圖片顯示出來
3.如果在內(nèi)存和磁盤緩存中都沒有找到奴迅,就會(huì)向遠(yuǎn)程服務(wù)器發(fā)送請(qǐng)求,開始下載圖片
4.下載后的圖片會(huì)加入緩存中挺据,并寫入磁盤中
5.整個(gè)獲取圖片的過程都是在子線程中執(zhí)行取具,獲取到圖片后回到主線程將圖片顯示出來
SDWebImage原理:
調(diào)用類別的方法:
1.從內(nèi)存(字典)中找圖片(當(dāng)這個(gè)圖片在本次使用程序的過程中已經(jīng)被加載過),找到直接使用扁耐。
2.從沙盒中找(當(dāng)這個(gè)圖片在之前使用程序的過程中被加載過)暇检,找到使用,緩存到內(nèi)存中婉称。
3.從網(wǎng)絡(luò)上獲取块仆,使用构蹬,緩存到內(nèi)存,緩存到沙盒悔据。
21:iOS逆向傳值的幾種方法
- 代理
- 通知
- 單例
- Block
- Kvo
22.你們的App是如何處理本地?cái)?shù)據(jù)安全的(比如用戶名的密碼)庄敛?
https://blog.csdn.net/baize_security/article/details/52766981
23.說一下UITableViewCell的卡頓你是怎么優(yōu)化的?
24.為什么一定要在主線程里面更新UI蜜暑?
因?yàn)樽泳€程代碼執(zhí)行完畢了,又自動(dòng)進(jìn)入到了主線程,執(zhí)行了子線程中的UI
更新的函數(shù)棧,這中間的時(shí)間非常的短,就讓大家誤以為分線程可以更新
UI铐姚。如果子線程一直在運(yùn)行,則子線程中的UI更新的函數(shù)棧主線程無法獲
知,即無法更新只有極少數(shù)的UI能,因?yàn)殚_辟線程時(shí)會(huì)獲取當(dāng)前環(huán)境,如點(diǎn)
擊某個(gè)按鈕,這個(gè)按鈕響應(yīng)的方法是開辟一個(gè)子線程,在子線程中對(duì)該按鈕
進(jìn)行UI更新是能及時(shí)的,如換標(biāo)題,換背景圖,但這沒有任何意義UI操作并
不是線程安全的,多線程更新UI會(huì)造成死鎖,競(jìng)爭(zhēng)條件等多種問題。
iOS推薦UI因?yàn)樽泳€程代碼執(zhí)行完畢了,又自動(dòng)進(jìn)入到了主線程,執(zhí)行了子
線程中的UI更新的函數(shù)棧,這中間的時(shí)間非常的短,就讓大家誤以為分線程
可以更新]UI肛捍。如果子線程一直在運(yùn)行,則子線程中的UI更新的函數(shù)棧 主線程無法獲知,即無法更新
只有極少數(shù)的UI能,因?yàn)殚_辟線程時(shí)會(huì)獲取當(dāng)前環(huán)境,如點(diǎn)擊某個(gè)按鈕,這
個(gè)按鈕響應(yīng)的方法是開辟一個(gè)子線程,在子線程中對(duì)該按鈕進(jìn)行UI 更新是
能及時(shí)的,如換標(biāo)題,換背景圖,但這沒有任何意義 .
UI操作并不是線程安全的,多線程更新UI會(huì)造成死鎖,競(jìng)爭(zhēng)條件等多種問
題隐绵。iOS推薦UI操作在主線程中進(jìn)行,避免出現(xiàn)crash等無法預(yù)知的問題。
比如TableView的刷新,有可能線程a往模型數(shù)組中添加了數(shù)據(jù)并刷新
tableView,tableView調(diào)用了
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
得知每組cell的個(gè)數(shù),但是就在tableView調(diào)用
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath方法的時(shí)候,
線程b將模型數(shù)組里面的數(shù)據(jù)刪除干凈了,如果此時(shí)在- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
方法里訪問模型數(shù)組,就會(huì)出現(xiàn)數(shù)組越界,這在網(wǎng)絡(luò)請(qǐng)求數(shù)據(jù)的時(shí)候很容易
出現(xiàn),一定要確定數(shù)據(jù)返回的block或者delegate是在哪個(gè)線程,如果是子
線程一定要回主線程刷新UI拙毫。
25.說一下多線程依许,你平常是怎么用的?
http://www.cocoachina.com/ios/20170829/20404.html iOS多線程詳解
高階
26.objc中向一個(gè)nil對(duì)象發(fā)送消息將會(huì)發(fā)生什么缀蹄?
在 Objective-C 中向 nil 發(fā)送消息是完全有效的——只是在運(yùn)行時(shí)不會(huì)有任何作用:
如果一個(gè)方法返回值是一個(gè)對(duì)象峭跳,那么發(fā)送給nil的消息將返回0(nil)。例如:
Person * motherInlaw = [[aPerson spouse] mother];
如果 spouse 對(duì)象為 nil缺前,那么發(fā)送給 nil 的消息 mother 也將返回 nil蛀醉。
如果方法返回值為指針類型,其指針大小為小于或者等于sizeof(void*)衅码,float拯刁,double,long double 或者 long long 的整型標(biāo)量逝段,發(fā)送給 nil 的消息將返回0垛玻。
如果方法返回值為結(jié)構(gòu)體,發(fā)送給 nil 的消息將返回0。結(jié)構(gòu)體中各個(gè)字段的值將都是0奶躯。
如果方法的返回值不是上述提到的幾種情況帚桩,那么發(fā)送給 nil 的消息的返回值將是未定義的。
具體原因如下:
objc是動(dòng)態(tài)語言嘹黔,每個(gè)方法在運(yùn)行時(shí)會(huì)被動(dòng)態(tài)轉(zhuǎn)為消息發(fā)送账嚎,即:objc_msgSend(receiver, selector)。
那么儡蔓,為了方便理解這個(gè)內(nèi)容醉锄,還是貼一個(gè)objc的源代碼:
// runtime.h(類在runtime中的定義)
// http://weibo.com/luohanchenyilong/
// https://github.com/ChenYilong
struct objc_class {
Class isa OBJC_ISA_AVAILABILITY; //isa指針指向Meta Class,因?yàn)镺bjc的類的本身也是一個(gè)Object浙值,為了處理這個(gè)關(guān)系恳不,runtime就創(chuàng)造了Meta Class,當(dāng)給類發(fā)送[NSObject alloc]這樣消息時(shí)开呐,實(shí)際上是把這個(gè)消息發(fā)給了Class Object
#if !__OBJC2__
Class super_class OBJC2_UNAVAILABLE; // 父類
const char *name OBJC2_UNAVAILABLE; // 類名
long version OBJC2_UNAVAILABLE; // 類的版本信息烟勋,默認(rèn)為0
long info OBJC2_UNAVAILABLE; // 類信息规求,供運(yùn)行期使用的一些位標(biāo)識(shí)
long instance_size OBJC2_UNAVAILABLE; // 該類的實(shí)例變量大小
struct objc_ivar_list *ivars OBJC2_UNAVAILABLE; // 該類的成員變量鏈表
struct objc_method_list **methodLists OBJC2_UNAVAILABLE; // 方法定義的鏈表
struct objc_cache *cache OBJC2_UNAVAILABLE; // 方法緩存,對(duì)象接到一個(gè)消息會(huì)根據(jù)isa指針查找消息對(duì)象卵惦,這時(shí)會(huì)在method Lists中遍歷阻肿,如果cache了,常用的方法調(diào)用時(shí)就能夠提高調(diào)用的效率沮尿。
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE; // 協(xié)議鏈表
#endif
} OBJC2_UNAVAILABLE;
objc在向一個(gè)對(duì)象發(fā)送消息時(shí)丛塌,runtime庫(kù)會(huì)根據(jù)對(duì)象的isa指針找到該對(duì)
象實(shí)際所屬的類,然后在該類中的方法列表以及其父類方法列表中尋找
方法運(yùn)行畜疾,然后在發(fā)送消息的時(shí)候赴邻,objc_msgSend方法不會(huì)返回值,所
謂的返回內(nèi)容都是具體調(diào)用時(shí)執(zhí)行的啡捶。那么姥敛,回到本題,如果向一個(gè)nil
對(duì)象發(fā)送消息瞎暑,首先在尋找對(duì)象的isa指針時(shí)就是0地址返回了彤敛,所以不會(huì)出現(xiàn)任何錯(cuò)誤。
27.runloop和線程有什么關(guān)系了赌?
runloop與線程是一一對(duì)應(yīng)的墨榄,一個(gè)runloop對(duì)應(yīng)一個(gè)核心的線程,為什么說是核心的勿她,是因?yàn)閞unloop是可以嵌套的袄秩,但是核心的只能有一個(gè),他們的關(guān)系保存在一個(gè)全局的字典里嫂拴。
runloop是來管理線程的,當(dāng)線程的runloop被開啟后贮喧,線程會(huì)在執(zhí)行完任務(wù)后進(jìn)入休眠狀態(tài)筒狠,有了任務(wù)就會(huì)被喚醒去執(zhí)行任務(wù)。
runloop在第一次獲取時(shí)被創(chuàng)建箱沦,在線程結(jié)束時(shí)被銷毀辩恼。
對(duì)于主線程來說,runloop在程序一啟動(dòng)就默認(rèn)創(chuàng)建好了谓形。
對(duì)于子線程來說灶伊,runloop是懶加載的,只有當(dāng)我們使用的時(shí)候才會(huì)創(chuàng)
建寒跳,所以在子線程用定時(shí)器要注意:確保子線程的runloop被創(chuàng)建聘萨,不然定時(shí)器不會(huì)回調(diào)。
28.Objective-C中創(chuàng)建線程的方法是什么童太?如果在主線程中執(zhí)行代碼米辐,方法是什么胸完?如果想延時(shí)執(zhí)行代碼、方法又是什么翘贮?
線程創(chuàng)建有三種方法:使用NSThread創(chuàng)建赊窥、使用GCD的dispatch、使用子類化的NSOperation,然后將其加入NSOperationQueue;在主線程執(zhí)行代碼狸页,方法是performSelectorOnMainThread锨能,如果想延時(shí)執(zhí)行代碼可以用performSelector:onThread:withObject:waitUntilDone:
29.KVC的底層實(shí)現(xiàn)?
當(dāng)一個(gè)對(duì)象調(diào)用setValue方法時(shí)芍耘,方法內(nèi)部會(huì)做以下操作:
1). 檢查是否存在相應(yīng)的key的set方法址遇,如果存在,就調(diào)用set方法齿穗。
2). 如果set方法不存在傲隶,就會(huì)查找與key相同名稱并且?guī)聞澗€的成員變量,如果有窃页,則直接給成員變量屬性賦值跺株。
3). 如果沒有找到_key,就會(huì)查找相同名稱的屬性key脖卖,如果有就直接賦值乒省。
4). 如果還沒有找到,則調(diào)用valueForUndefinedKey:和setValue:forUndefinedKey:方法畦木。這些方法的默認(rèn)實(shí)現(xiàn)都是拋出異常袖扛,我們可以根據(jù)需要重寫它們。
30. 如何對(duì)iOS設(shè)備進(jìn)行性能測(cè)試十籍?
Profile-> Instruments ->Time Profiler
開發(fā)項(xiàng)目時(shí)你是怎么檢查內(nèi)存泄露蛆封?
1). 靜態(tài)分析 analyze。
2). instruments工具里面有個(gè)leak可以動(dòng)態(tài)分析勾栗。
31. GCD 與 NSOperation 的區(qū)別:
GCD 和 NSOperation 都是用于實(shí)現(xiàn)多線程:
GCD 基于C語言的底層API惨篱,GCD主要與block結(jié)合使用,代碼簡(jiǎn)潔高效围俘。
NSOperation 屬于Objective-C類砸讳,是基于GCD更高一層的封裝。復(fù)雜任務(wù)一般用NSOperation實(shí)現(xiàn)
32. 如何用GCD同步若干個(gè)異步調(diào)用界牡?(如根據(jù)若干個(gè)url異步加載多張圖片簿寂,然后在都下載完成后合成一張整圖)
// 使用Dispatch Group追加block到Global Group Queue,這些block如果全部執(zhí)行完畢,就會(huì)執(zhí)行Main Dispatch Queue中的結(jié)束處理的block宿亡。
// 創(chuàng)建隊(duì)列組
dispatch_group_t group = dispatch_group_create();
// 獲取全局并發(fā)隊(duì)列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_async(group, queue, ^{ /*加載圖片1 */ });
dispatch_group_async(group, queue, ^{ /*加載圖片2 */ });
dispatch_group_async(group, queue, ^{ /*加載圖片3 */ });
// 當(dāng)并發(fā)隊(duì)列組中的任務(wù)執(zhí)行完畢后才會(huì)執(zhí)行這里的代碼
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// 合并圖片
});
33.什么是 RunLoop
從字面上講就是運(yùn)行循環(huán)常遂,它內(nèi)部就是do-while循環(huán),在這個(gè)循環(huán)內(nèi)部不斷地處理各種任務(wù)挽荠。 一個(gè)線程對(duì)應(yīng)一個(gè)RunLoop烈钞,基本作用就是保持程序的持續(xù)運(yùn)行泊碑,處理app中的各種事件。通過runloop毯欣,有事運(yùn)行馒过,沒事就休息,可以節(jié)省cpu資源酗钞,提高程序性能腹忽。 主線程的run loop默認(rèn)是啟動(dòng)的。iOS的應(yīng)用程序里面砚作,程序啟動(dòng)后會(huì)有一個(gè)如下的main()函數(shù)intmain(intargc, char* argv[]) {@autoreleasepool{returnUIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } }
34.什么是 Runtime
Runtime又叫運(yùn)行時(shí)窘奏,是一套底層的C語言API,其為iOS內(nèi)部的核心之一葫录,我們平時(shí)編寫的OC代碼着裹,底層都是基于它來實(shí)現(xiàn)的。
1). 使用時(shí)需要導(dǎo)入的頭文件 <objc/message.h> <objc/runtime.h>
2). Runtime 運(yùn)行時(shí)機(jī)制米同,它是一套C語言庫(kù)骇扇。
3). 實(shí)際上我們編寫的所有OC代碼,最終都是轉(zhuǎn)成了runtime庫(kù)的東西面粮。 比如: 類轉(zhuǎn)成了 Runtime 庫(kù)里面的結(jié)構(gòu)體等數(shù)據(jù)類型少孝, 方法轉(zhuǎn)成了 Runtime 庫(kù)里面的C語言函數(shù), 平時(shí)調(diào)方法都是轉(zhuǎn)成了 objc_msgSend 函數(shù)(所以說OC有個(gè)消息發(fā)送機(jī)制)// OC是動(dòng)態(tài)語言熬苍,每個(gè)方法在運(yùn)行時(shí)會(huì)被動(dòng)態(tài)轉(zhuǎn)為消息發(fā)送稍走,即:objc_msgSend(receiver, selector)。// [stu show]; 在objc動(dòng)態(tài)編譯時(shí)柴底,會(huì)被轉(zhuǎn)意為:objc_msgSend(stu, @selector(show));
4). 因此婿脸,可以說 Runtime 是OC的底層實(shí)現(xiàn),是OC的幕后執(zhí)行者柄驻。
36.__block修飾的變量為什么能在block里面能改變其值狐树?
默認(rèn)情況下,在block中訪問的外部變量是復(fù)制過去的凿歼,即:寫操作不對(duì)
原變量生效褪迟。但是你可以加上 __block
我們都知道:block不允許修改外部變量的值冗恨,這里所說的外部變量的
值答憔,指的是棧中指針的內(nèi)存地址。
__block 所起到的作用就是只要觀察到該變量被 block 所持有掀抹,就將“外
部變量”在棧中的內(nèi)存地址放到了堆中虐拓。進(jìn)而在block內(nèi)部也可以修改外部變量的值。
37.block的實(shí)質(zhì)是什么傲武?有幾種block蓉驹?分別是怎樣產(chǎn)生的城榛?
iOS Block理解
http://www.reibang.com/p/9e9a6d7eba92
iOS底層原理總結(jié) - 探尋block的本質(zhì)
http://www.cocoachina.com/ios/20180628/23965.html
block本質(zhì)上也是一個(gè)oc對(duì)象,他內(nèi)部也有一個(gè)isa指針态兴。block是封裝了函數(shù)調(diào)用以及函數(shù)調(diào)用環(huán)境的OC對(duì)象狠持。
局部變量都會(huì)被block捕獲,自動(dòng)變量是值捕獲瞻润,靜態(tài)變量為地址捕獲喘垂。全局變量則不會(huì)被block捕獲
即使block中使用的是實(shí)例對(duì)象的屬性,block中捕獲的仍然是實(shí)例對(duì)象绍撞,并通過實(shí)例對(duì)象通過不同的方式去獲取使用到的屬性正勒。
block最終都是繼承自NSBlock類型,而NSBlock繼承于NSObjcet傻铣。那么block其中的isa指針其實(shí)是來自NSObject中的章贞。這也更加印證了block的本質(zhì)其實(shí)就是OC對(duì)象。
block有3中類型
__NSGlobalBlock__ ( _NSConcreteGlobalBlock )
__NSStackBlock__ ( _NSConcreteStackBlock )
__NSMallocBlock__ ( _NSConcreteMallocBlock )
int main(int argc, const char * argv[]) {
@autoreleasepool {
// 1. 內(nèi)部沒有調(diào)用外部變量的block
void (^block1)(void) = ^{
NSLog(@"Hello");
};
// 2. 內(nèi)部調(diào)用外部變量的block
int a = 10;
void (^block2)(void) = ^{
NSLog(@"Hello - %d",a);
};
// 3. 直接調(diào)用的block的class
NSLog(@"%@ %@ %@", [block1 class], [block2 class], [^{
NSLog(@"%d",a);
} class]);
}
return 0;
}
38.看過哪些三方庫(kù)非洲?說一下實(shí)現(xiàn)原理以及好在哪里鸭限?
39.說一下HTTP和HTTPs的請(qǐng)求過程?
HTTP協(xié)議(HyperText Transfer Protocol怪蔑,超文本傳輸協(xié)議):是一種
發(fā)布和接收 HTML頁面的方法里覆。
HTTPS(Hypertext Transfer Protocol over Secure Socket Layer)簡(jiǎn)單
講是HTTP的安全版,在HTTP下加入SSL層缆瓣。
SSL(Secure Sockets Layer 安全套接層)主要用于Web的安全傳輸協(xié)
議喧枷,在傳輸層對(duì)網(wǎng)絡(luò)連接進(jìn)行加密,保障在Internet上數(shù)據(jù)傳輸?shù)陌踩?
HTTP的端口號(hào)為80弓坞,
HTTPS的端口號(hào)為443
https://blog.csdn.net/xun527/article/details/78387345
OSI 各層功能
應(yīng)用層
與其它計(jì)算機(jī)進(jìn)行通訊的一個(gè)應(yīng)用隧甚,它是對(duì)應(yīng)應(yīng)用程序的通信服務(wù)的。例如渡冻,一個(gè)沒有通信功能的字處理程序就不能執(zhí)行通信的代碼戚扳,從事字處理工作的程序員也不關(guān)心OSI的第7層。但是族吻,如果添加了一個(gè)傳輸文件的選項(xiàng)帽借,那么字處理器的程序員就需要實(shí)現(xiàn)OSI的第7層。示例:TELNET超歌,HTTP砍艾,F(xiàn)TP,NFS巍举,SMTP等脆荷。
表示層
這一層的主要功能是定義數(shù)據(jù)格式及加密。例如,F(xiàn)TP允許你選擇以二進(jìn)制或ASCII格式傳輸蜓谋。如果選擇二進(jìn)制梦皮,那么發(fā)送方和接收方不改變文件的內(nèi)容。如果選擇ASCII格式桃焕,發(fā)送方將把文本從發(fā)送方的字符集轉(zhuǎn)換成標(biāo)準(zhǔn)的ASCII后發(fā)送數(shù)據(jù)剑肯。在接收方將標(biāo)準(zhǔn)的ASCII轉(zhuǎn)換成接收方計(jì)算機(jī)的字符集。示例:加密观堂,ASCII等退子。
會(huì)話層
它定義了如何開始、控制和結(jié)束一個(gè)會(huì)話型将,包括對(duì)多個(gè)雙向消息的控制和管理寂祥,以便在只完成連續(xù)消息的一部分時(shí)可以通知應(yīng)用,從而使表示層看到的數(shù)據(jù)是連續(xù)的七兜,在某些情況下丸凭,如果表示層收到了所有的數(shù)據(jù),則用數(shù)據(jù)代表表示層腕铸。示例:RPC惜犀,SQL等。
傳輸層
這層的功能包括是否選擇差錯(cuò)恢復(fù)協(xié)議還是無差錯(cuò)恢復(fù)協(xié)議狠裹,及在同一主機(jī)上對(duì)不同應(yīng)用的數(shù)據(jù)流的輸入進(jìn)行復(fù)用虽界,還包括對(duì)收到的順序不對(duì)的數(shù)據(jù)包的重新排序功能。示例:TCP涛菠,UDP莉御,SPX。
網(wǎng)絡(luò)層
這層對(duì)端到端的包傳輸進(jìn)行定義俗冻,它定義了能夠標(biāo)識(shí)所有結(jié)點(diǎn)的邏輯地址礁叔,還定義了路由實(shí)現(xiàn)的方式和學(xué)習(xí)的方式。為了適應(yīng)最大傳輸單元長(zhǎng)度小于包長(zhǎng)度的傳輸介質(zhì)迄薄,網(wǎng)絡(luò)層還定義了如何將一個(gè)包分解成更小的包的分段方法琅关。示例:IP,IPX等讥蔽。
數(shù)據(jù)鏈路層
它定義了在單個(gè)鏈路上如何傳輸數(shù)據(jù)涣易。這些協(xié)議與被討論的各種介質(zhì)有關(guān)。示例:ATM冶伞,F(xiàn)DDI等新症。
物理層
OSI的物理層規(guī)范是有關(guān)傳輸介質(zhì)的特這些規(guī)范通常也參考了其他組織制定的標(biāo)準(zhǔn)。連接頭碰缔、幀账劲、幀的使用戳护、電流金抡、編碼及光調(diào)制等都屬于各種物理層規(guī)范中的內(nèi)容瀑焦。物理層常用多個(gè)規(guī)范完成對(duì)所有細(xì)節(jié)的定義。示例:Rj45梗肝,802.3等榛瓮。