iOS最新面試題匯總:
iOS最新面試題匯總(一)
iOS最新面試題匯總(二)
iOS最新面試題匯總(三)
iOS最新面試題匯總(四)
-
Runtime實(shí)現(xiàn)的機(jī)制是什么随闺,怎么用琅翻,一般用于干嘛又固?
1). 使用時需要導(dǎo)入的頭文件 <objc/message.h> <objc/runtime.h>
2). Runtime 運(yùn)行時機(jī)制何荚,它是一套C語言庫毯盈。
3). 實(shí)際上我們編寫的所有OC代碼缔恳,最終都是轉(zhuǎn)成了runtime庫的東西宝剖。
比如:
類轉(zhuǎn)成了 Runtime 庫里面的結(jié)構(gòu)體等數(shù)據(jù)類型,
方法轉(zhuǎn)成了 Runtime 庫里面的C語言函數(shù)歉甚,
平時調(diào)方法都是轉(zhuǎn)成了 objc_msgSend 函數(shù)(所以說OC有個消息發(fā)送機(jī)制)
// OC是動態(tài)語言万细,每個方法在運(yùn)行時會被動態(tài)轉(zhuǎn)為消息發(fā)送,即:objc_msgSend(receiver, selector)纸泄。
// [stu show]; 在objc動態(tài)編譯時赖钞,會被轉(zhuǎn)意為:objc_msgSend(stu, @selector(show));
4). 因此,可以說 Runtime 是OC的底層實(shí)現(xiàn)聘裁,是OC的幕后執(zhí)行者雪营。
-
有了Runtime庫,能做什么事情呢衡便?
Runtime庫里面包含了跟類献起、成員變量、方法相關(guān)的API镣陕。
比如:
(1)獲取類里面的所有成員變量谴餐。
(2)為類動態(tài)添加成員變量。
(3)動態(tài)改變類的方法實(shí)現(xiàn)呆抑。
(4)為類動態(tài)添加新的方法等岂嗓。
因此,有了Runtime理肺,想怎么改就怎么改摄闸。
-
什么是 Method Swizzle(黑魔法)善镰,什么情況下會使用妹萨?
1). 在沒有一個類的實(shí)現(xiàn)源碼的情況下,想改變其中一個方法的實(shí)現(xiàn)炫欺,除了繼承它重寫乎完、和借助類別重名方法暴力搶先之外,還有更加靈活的方法 Method Swizzle品洛。
2). Method Swizzle 指的是改變一個已存在的選擇器對應(yīng)的實(shí)現(xiàn)的過程树姨。OC中方法的調(diào)用能夠在運(yùn)行時通過改變摩桶,通過改變類的調(diào)度表中選擇器到最終函數(shù)間的映射關(guān)系。
3). 在OC中調(diào)用一個方法帽揪,其實(shí)是向一個對象發(fā)送消息硝清,查找消息的唯一依據(jù)是selector的名字。利用OC的動態(tài)特性转晰,可以實(shí)現(xiàn)在運(yùn)行時偷換selector對應(yīng)的方法實(shí)現(xiàn)芦拿。
4). 每個類都有一個方法列表,存放著selector的名字和方法實(shí)現(xiàn)的映射關(guān)系查邢。IMP有點(diǎn)類似函數(shù)指針蔗崎,指向具體的方法實(shí)現(xiàn)。
5). 我們可以利用 method_exchangeImplementations 來交換2個方法中的IMP扰藕。
6). 我們可以利用 class_replaceMethod 來修改類缓苛。
7). 我們可以利用 method_setImplementation 來直接設(shè)置某個方法的IMP。
8). 歸根結(jié)底邓深,都是偷換了selector的IMP未桥。
-
_objc_msgForward 函數(shù)是做什么的,直接調(diào)用它將會發(fā)生什么庐完?
答:_objc_msgForward是 IMP 類型钢属,用于消息轉(zhuǎn)發(fā)的:當(dāng)向一個對象發(fā)送一條消息,但它并沒有實(shí)現(xiàn)的時候门躯,_objc_msgForward會嘗試做消息轉(zhuǎn)發(fā)淆党。
-
什么是 TCP / UDP ?
TCP:傳輸控制協(xié)議。
UDP:用戶數(shù)據(jù)協(xié)議讶凉。
TCP 是面向連接的染乌,建立連接需要經(jīng)歷三次握手,是可靠的傳輸層協(xié)議懂讯。
UDP 是面向無連接的荷憋,數(shù)據(jù)傳輸是不可靠的,它只管發(fā)褐望,不管收不收得到勒庄。
簡單的說,TCP注重數(shù)據(jù)安全瘫里,而UDP數(shù)據(jù)傳輸快點(diǎn)实蔽,但安全性一般。
通信底層原理(OSI七層模型)
OSI采用了分層的結(jié)構(gòu)化技術(shù)谨读,共分七層:
物理層局装、數(shù)據(jù)鏈路層、網(wǎng)絡(luò)層、傳輸層铐尚、會話層拨脉、表示層、應(yīng)用層宣增。
-
介紹一下XMPP玫膀?
XMPP是一種以XML為基礎(chǔ)的開放式實(shí)時通信協(xié)議。
簡單的說爹脾,XMPP就是一種協(xié)議匆骗,一種規(guī)定。就是說誉简,在網(wǎng)絡(luò)上傳東西碉就,XMPP就是規(guī)定你上傳大小的格式。
-
OC中創(chuàng)建線程的方法是什么闷串?如果在主線程中執(zhí)行代碼瓮钥,方法是什么?
// 創(chuàng)建線程的方法
- [NSThread detachNewThreadSelector:nil toTarget:nil withObject:nil]
- [self performSelectorInBackground:nil withObject:nil];
- [[NSThread alloc] initWithTarget:nil selector:nil object:nil];
- dispatch_async(dispatch_get_global_queue(0, 0), ^{});
- [[NSOperationQueue new] addOperation:nil];
// 主線程中執(zhí)行代碼的方法
- [self performSelectorOnMainThread:nil withObject:nil waitUntilDone:YES];
- dispatch_async(dispatch_get_main_queue(), ^{});
- [[NSOperationQueue mainQueue] addOperation:nil];
-
tableView的重用機(jī)制烹吵?
答:UITableView 通過重用單元格來達(dá)到節(jié)省內(nèi)存的目的: 通過為每個單元格指定一個重用標(biāo)識符碉熄,即指定了單元格的種類,當(dāng)屏幕上的單元格滑出屏幕時,系統(tǒng)會把這個單元格添加到重用隊(duì)列中肋拔,等待被重用锈津,當(dāng)有新單元格從屏幕外滑入屏幕內(nèi)時,從重用隊(duì)列中找看有沒有可以重用的單元格凉蜂,如果有琼梆,就拿過來用,如果沒有就創(chuàng)建一個來使用窿吩。
-
用偽代碼寫一個線程安全的單例模式
static id _instance;
+ (id)allocWithZone:(struct _NSZone *)zone {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [super allocWithZone:zone];
});
return _instance;
}
+ (instancetype)sharedData {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[self alloc] init];
});
return _instance;
}
- (id)copyWithZone:(NSZone *)zone {
return _instance;
}
-
如何實(shí)現(xiàn)視圖的變形?
答:通過修改view的 transform 屬性即可茎杂。
-
在手勢對象基礎(chǔ)類UIGestureRecognizer的常用子類手勢類型中哪兩個手勢發(fā)生后,響應(yīng)只會執(zhí)行一次纫雁?
答:UITapGestureRecognizer,UISwipeGestureRecognizer是一次性手勢,手勢發(fā)生后,響應(yīng)只會執(zhí)行一次煌往。
-
字符串常用方法:
NSString *str = @"abc*123";
NSArray *arr = [str componentsSeparatedByString:@"*"]; //以目標(biāo)字符串把原 字符串分割成兩部分,存到數(shù)組中轧邪。@[@"abc", @"123"];
-
如何高性能的給 UIImageView 加個圓角?
不好的解決方案:使用下面的方式會強(qiáng)制Core Animation提前渲染屏幕的離屏繪制, 而離屏繪制就會給性能帶來負(fù)面影響刽脖,會有卡頓的現(xiàn)象出現(xiàn)。
self.view.layer.cornerRadius = 5.0f;
self.view.layer.masksToBounds = YES;
正確的解決方案:使用繪圖技術(shù)
- (UIImage *)circleImage {
// NO代表透明
UIGraphicsBeginImageContextWithOptions(self.size, NO, 0.0);
// 獲得上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 添加一個圓
CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);
CGContextAddEllipseInRect(ctx, rect);
// 裁剪
CGContextClip(ctx);
// 將圖片畫上去
[self drawInRect:rect];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
// 關(guān)閉上下文
UIGraphicsEndImageContext();
return image;
}
還有一種方案:使用了貝塞爾曲線"切割"個這個圖片, 給UIImageView 添加了的圓角忌愚,其實(shí)也是通過繪圖技術(shù)來實(shí)現(xiàn)的曲管。
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
imageView.center = CGPointMake(200, 300);
UIImage *anotherImage = [UIImage imageNamed:@"image"];
UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 1.0);
[[UIBezierPath bezierPathWithRoundedRect:imageView.bounds
cornerRadius:50] addClip];
[anotherImage drawInRect:imageView.bounds];
imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[self.view addSubview:imageView];
-
你是怎么封裝一個view的
1). 可以通過純代碼或者xib的方式來封裝子控件
2). 建立一個跟view相關(guān)的模型,然后將模型數(shù)據(jù)傳給view菜循,通過模型上的數(shù)據(jù)給view的子控件賦值
/**
* 純代碼初始化控件時一定會走這個方法
*/
- (instancetype)initWithFrame:(CGRect)frame {
if(self = [super initWithFrame:frame]) {
[self setupUI];
}
return self;
}
/**
* 通過xib初始化控件時一定會走這個方法
*/
- (id)initWithCoder:(NSCoder *)aDecoder {
if(self = [super initWithCoder:aDecoder]) {
[self setupUI];
}
return self;
}
- (void)setupUI {
// 初始化代碼
}
-
HTTP協(xié)議中 POST 方法和 GET 方法有那些區(qū)別?
1. GET用于向服務(wù)器請求數(shù)據(jù)翘地,POST用于提交數(shù)據(jù)
2. GET請求,請求參數(shù)拼接形式暴露在地址欄癌幕,而POST請求參數(shù)則放在請求體里面衙耕,因此GET請求不適合用于驗(yàn)證密碼等操作
3. GET請求的URL有長度限制,POST請求不會有長度限制
-
請簡單的介紹下APNS發(fā)送系統(tǒng)消息的機(jī)制
APNS優(yōu)勢:杜絕了類似安卓那種為了接受通知不停在后臺喚醒程序保持長連接的行為勺远,由iOS系統(tǒng)和APNS進(jìn)行長連接替代橙喘。
APNS的原理:
1). 應(yīng)用在通知中心注冊,由iOS系統(tǒng)向APNS請求返回設(shè)備令牌(device Token)
2). 應(yīng)用程序接收到設(shè)備令牌并發(fā)送給自己的后臺服務(wù)器
3). 服務(wù)器把要推送的內(nèi)容和設(shè)備發(fā)送給APNS
4). APNS根據(jù)設(shè)備令牌找到設(shè)備胶逢,再由iOS根據(jù)APPID把推送內(nèi)容展示
聯(lián)系
github地址:https://github.com/meetly
希望大家多多指教厅瞎!