iOS面試題整理自用(一)

面試題摘錄于網(wǎng)絡(luò), 用于個人復(fù)習(xí)使用。

  1. id 聲明的對象有什么特性?

答:id 聲明的對象具有運行時的特性,即可以指向任意類型的Objcetive-C的對象

  1. Category(類別)、 Extension(擴展)和繼承的區(qū)別

區(qū)別:

  1. 分類有名字,類擴展沒有分類名字,是一種特殊的分類。

  2. 分類只能擴展方法(屬性僅僅是聲明,并沒真正實現(xiàn)),類擴展可以擴展屬性、成員變量和方法。

  3. 繼承可以增加,修改或者刪除方法,并且可以增加屬性。

  4. 我們說的OC是動態(tài)運行時語言是什么意思?

答:主要是將數(shù)據(jù)類型的確定由編譯時,推遲到了運行時。簡單來說, 運行時機制使我們直到運行時才去決定一個對象的類別,以及調(diào)用該類別對象指定方法

  1. iOS runtime 有哪些應(yīng)用,感覺實際項目幾乎用不上~?

  2. 用runtime寫的業(yè)務(wù)場景比較少且比較隱蔽,寫了一大堆runtime代碼,對外不可見,用著很爽,造輪子的時候用的到

  3. 閱讀Aspect源碼 AOP

  4. 什么是 KVO 和 KVC?
    1). KVC(Key-Value-Coding):鍵值編碼 是一種通過字符串間接訪問對象的方式(即給屬性賦值)
    [stu1 setValue:@"張三" forKey:@"nameLabel.text"]; // 跨層賦值

6.ViewController生命周期
按照執(zhí)行順序排列:

  1. initWithCoder:通過nib文件初始化時觸發(fā)。
  2. awakeFromNib:nib文件被加載的時候,會發(fā)生一個awakeFromNib的消息到nib文件中的每個對象。
  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上消失。

7.方法和選擇器有何不同?
selector是一個方法的名字,方法是一個組合體,包含了名字和實現(xiàn)。

8.你是否接觸過OC中的反射機制?簡單聊一下概念和使用
1). class反射
通過類名的字符串形式實例化對象。
Class class = NSClassFromString(@"student");
Student *stu = [[class alloc] init];
將類名變?yōu)樽址?br> Class class =[Student class];
NSString className = NSStringFromClass(class);
2). SEL的反射
通過方法的字符串形式實例化方法。
SEL selector = NSSelectorFromString(@"setName");
[stu performSelector:selector withObject:@"Mike"];
將方法變成字符串。
NSStringFromSelector(@selector
(setName:));

9.如何對iOS設(shè)備進行性能測試?怎么檢查內(nèi)存泄露?
Profile-> Instruments ->Time Profiler 性能測試

1). 靜態(tài)分析 analyze。
2). instruments工具里面有個leak可以動態(tài)分析。

10.什么是謂詞?
謂詞就是通過NSPredicate給定的邏輯條件作為約束條件,完成對數(shù)據(jù)的篩選。
//定義謂詞對象,謂詞對象中包含了過濾條件(過濾條件比較多) NSPredicate *predicate = [NSPredicate predicateWithFormat:@"age<%d",30]; //使用謂詞條件過濾數(shù)組中的元素,過濾之后返回查詢的結(jié)果 NSArray *array = [persons filteredArrayUsingPredicate:predicate];

11.isa指針問題 有什么作用?
isa:是一個Class 類型的指針. 每個實例對象有個isa的指針,他指向?qū)ο蟮念?而Class里也有個isa的指針, 指向meteClass(元類)。元類保存了類方法的列表。當(dāng)類方法被調(diào) 用時,先會從本身查找類方法的實現(xiàn),如果沒有,元類會向他父類查找該方法。同時注意的是:元類(meteClass)也是類,它也是對象。元類也有isa指針,它的isa指針最終指向的是一個根元類(root meteClass)。根元類的isa指針指向本身,這樣形成了一個封閉的內(nèi)循環(huán)。

指向他的類對象,從而可以找到對象上的方法。

12.如何訪問并修改一個類的私有屬性?
1). 一種是通過KVC獲取。
2). 通過runtime訪問并修改私有屬性。

13.isKindOfClass、isMemberOfClass、selector作用分別是什么
isKindOfClass:作用是某個對象屬于某個類型或者繼承自某類型。
isMemberOfClass:某個對象確切屬于某個類型。
selector:通過方法名,獲取在內(nèi)存中的函數(shù)的入口地址。

14.block的注意點
1). 在block內(nèi)部使用外部指針且會造成循環(huán)引用情況下,需要用__week修飾外部指針:
__weak typeof(self) weakSelf = self;
2). 在block內(nèi)部如果調(diào)用了延時函數(shù)還使用弱指針會取不到該指針,因為已經(jīng)被銷毀了,需要在block內(nèi)部再將弱指針重新強引用一下。
__strong typeof(self) strongSelf = weakSelf;
3). 如果需要在block內(nèi)部改變外部棧區(qū)變量的話,需要在用__block修飾外部變量。

15.BAD_ACCESS在什么情況下出現(xiàn)?
答:這種問題在開發(fā)時經(jīng)常遇到。原因是訪問了野指針,比如訪問已經(jīng)釋放對象的成員變量或者發(fā)消息、死循環(huán)等。

16.lldb(gdb)常用的控制臺調(diào)試命令?
1). p 輸出基本類型。是打印命令,需要指定類型。是print的簡寫
p (int)[[[self view] subviews] count]
2). po 打印對象,會調(diào)用對象description方法。是print-object的簡寫
po [self view]
3). expr 可以在調(diào)試時動態(tài)執(zhí)行指定表達式,并將結(jié)果打印出來。常用于在調(diào)試過程中修改變量的值。
4). bt:打印調(diào)用堆棧,是thread backtrace的簡寫,加all可打印所有thread的堆棧
5). br l:是breakpoint list的簡寫

17.你一般是怎么用Instruments的?
Instruments里面工具很多,常用:
1). Time Profiler: 性能分析
2). Zombies:檢查是否訪問了僵尸對象,但是這個工具只能從上往下檢查,不智能。
3). Allocations:用來檢查內(nèi)存,寫算法的那批人也用這個來檢查。
4). Leaks:檢查內(nèi)存,看是否有內(nèi)存泄露。

18.iOS中常用的數(shù)據(jù)存儲方式有哪些?
數(shù)據(jù)存儲有四種方案:NSUserDefault、KeyChain、file、DB。
其中File有三種方式:plist、Archive(歸檔)
DB包括:SQLite、FMDB、CoreData

19.iOS的沙盒目錄結(jié)構(gòu)是怎樣的?
沙盒結(jié)構(gòu):
1). Application:存放程序源文件,上架前經(jīng)過數(shù)字簽名,上架后不可修改。
2). Documents:常用目錄,iCloud備份目錄,存放數(shù)據(jù)。(這里不能存緩存文件,否則上架不被通過)
3). Library:
Caches:存放體積大又不需要備份的數(shù)據(jù)。(常用的緩存路徑)
Preference:設(shè)置目錄,iCloud會備份設(shè)置信息。
4). tmp:存放臨時文件,不會被備份,而且這個文件下的數(shù)據(jù)有可能隨時被清除的可能。

20.GCD 與 NSOperation 的區(qū)別:
GCD 和 NSOperation 都是用于實現(xiàn)多線程:
GCD 基于C語言的底層API,GCD主要與block結(jié)合使用,代碼簡潔高效。
NSOperation 屬于Objective-C類,是基于GCD更高一層的封裝。復(fù)雜任務(wù)一般用NSOperation實現(xiàn)。

21.如何用GCD同步若干個異步調(diào)用?(如根據(jù)若干個url異步加載多張圖片,然后在都下載完成后合成一張整圖)
// 使用Dispatch Group追加block到Global Group Queue,這些block如果全部執(zhí)行完畢,就會執(zhí)行Main Dispatch Queue中的結(jié)束處理的block。
// 創(chuàng)建隊列組
dispatch_group_t group = dispatch_group_create();
// 獲取全局并發(fā)隊列
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ā)隊列組中的任務(wù)執(zhí)行完畢后才會執(zhí)行這里的代碼
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// 合并圖片
});

22.dispatch_barrier_async(柵欄函數(shù))的作用是什么?
1.在它前面的任務(wù)執(zhí)行結(jié)束后它才執(zhí)行,它后面的任務(wù)要等它執(zhí)行完成后才會開始執(zhí)行。
2.避免數(shù)據(jù)競爭

23.輸出結(jié)果

  • (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"1");
    dispatch_sync(dispatch_get_main_queue(), ^{
    NSLog(@"2");
    });
    NSLog(@"3");
    }
    // 只輸出:1。(主線程死鎖)

24.什么是 RunLoop
從字面上講就是運行循環(huán),它內(nèi)部就是do-while循環(huán),在這個循環(huán)內(nèi)部不斷地處理各種任務(wù)。
一個線程對應(yīng)一個RunLoop,基本作用就是保持程序的持續(xù)運行,處理app中的各種事件。通過runloop,有事運行,沒事就休息,可以節(jié)省cpu資源,提高程序性能。

主線程的run loop默認(rèn)是啟動的。iOS的應(yīng)用程序里面,程序啟動后會有一個如下的main()函數(shù)

25.Runtime實現(xiàn)的機制是什么,怎么用,一般用于干嘛?

1). 使用時需要導(dǎo)入的頭文件 <objc/message.h> <objc/runtime.h>
2). Runtime 運行時機制,它是一套C語言庫。
3). 實際上我們編寫的所有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ā)送機制)
// OC是動態(tài)語言,每個方法在運行時會被動態(tài)轉(zhuǎn)為消息發(fā)送,即:objc_msgSend(receiver, selector)。
// [stu show]; 在objc動態(tài)編譯時,會被轉(zhuǎn)意為:objc_msgSend(stu, @selector(show));
4). 因此,可以說 Runtime 是OC的底層實現(xiàn),是OC的幕后執(zhí)行者。

有了Runtime庫,能做什么事情呢?
Runtime庫里面包含了跟類、成員變量、方法相關(guān)的API。
比如:
(1)獲取類里面的所有成員變量。
(2)為類動態(tài)添加成員變量。
(3)動態(tài)改變類的方法實現(xiàn)。
(4)為類動態(tài)添加新的方法等。
因此,有了Runtime,想怎么改就怎么改。

26.什么是 Method Swizzle(黑魔法),什么情況下會使用?
1). 在沒有一個類的實現(xiàn)源碼的情況下,想改變其中一個方法的實現(xiàn),除了繼承它重寫、和借助類別重名方法暴力搶先之外,還有更加靈活的方法 Method Swizzle。
2). Method Swizzle 指的是改變一個已存在的選擇器對應(yīng)的實現(xiàn)的過程。OC中方法的調(diào)用能夠在運行時通過改變,通過改變類的調(diào)度表中選擇器到最終函數(shù)間的映射關(guān)系。
3). 在OC中調(diào)用一個方法,其實是向一個對象發(fā)送消息,查找消息的唯一依據(jù)是selector的名字。利用OC的動態(tài)特性,可以實現(xiàn)在運行時偷換selector對應(yīng)的方法實現(xiàn)。
4). 每個類都有一個方法列表,存放著selector的名字和方法實現(xiàn)的映射關(guān)系。IMP有點類似函數(shù)指針,指向具體的方法實現(xiàn)。
5). 我們可以利用 method_exchangeImplementations 來交換2個方法中的IMP。
6). 我們可以利用 class_replaceMethod 來修改類。
7). 我們可以利用 method_setImplementation 來直接設(shè)置某個方法的IMP。
8). 歸根結(jié)底,都是偷換了selector的IMP。

27._objc_msgForward 函數(shù)是做什么的,直接調(diào)用它將會發(fā)生什么?
答:_objc_msgForward是 IMP 類型,用于消息轉(zhuǎn)發(fā)的:當(dāng)向一個對象發(fā)送一條消息,但它并沒有實現(xiàn)的時候,_objc_msgForward會嘗試做消息轉(zhuǎn)發(fā)

28.什么是 TCP / UDP ?
TCP:傳輸控制協(xié)議。
UDP:用戶數(shù)據(jù)協(xié)議。

TCP 是面向連接的,建立連接需要經(jīng)歷三次握手,是可靠的傳輸層協(xié)議。
UDP 是面向無連接的,數(shù)據(jù)傳輸是不可靠的,它只管發(fā),不管收不收得到。
簡單的說,TCP注重數(shù)據(jù)安全,而UDP數(shù)據(jù)傳輸快點,但安全性一般。

29.通信底層原理(OSI七層模型)
OSI采用了分層的結(jié)構(gòu)化技術(shù),共分七層:
物理層、數(shù)據(jù)鏈路層、網(wǎng)絡(luò)層、傳輸層、會話層、表示層、應(yīng)用層。

30.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];

31.用偽代碼寫一個線程安全的單例模式
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;
    }

32.字符串常用方法:
NSString str = @"abc123";
NSArray arr = [str componentsSeparatedByString:@""]; //以目標(biāo)字符串把原字符串分割成兩部分,存到數(shù)組中。@[@"abc", @"123"];

33.如何高性能的給 UIImageView 加個圓角?

不好的解決方案:使用下面的方式會強制Core Animation提前渲染屏幕的離屏繪制, 而離屏繪制就會給性能帶來負面影響,會有卡頓的現(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ù)來實現(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];

34.你是怎么封裝一個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 {
    // 初始化代碼
    }
    ``

35.請簡單的介紹下APNS發(fā)送系統(tǒng)消息的機制

APNS優(yōu)勢:杜絕了類似安卓那種為了接受通知不停在后臺喚醒程序保持長連接的行為,由iOS系統(tǒng)和APNS進行長連接替代。
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)容展示

36.AFNetworking 底層原理分析

AFNetworking主要是對NSURLSession和NSURLConnection(iOS9.0廢棄)的封裝,其中主要有以下類:
1). AFHTTPRequestOperationManager:內(nèi)部封裝的是 NSURLConnection, 負責(zé)發(fā)送網(wǎng)絡(luò)請求, 使用最多的一個類。(3.0廢棄)
2). AFHTTPSessionManager:內(nèi)部封裝是 NSURLSession, 負責(zé)發(fā)送網(wǎng)絡(luò)請求,使用最多的一個類。
3). AFNetworkReachabilityManager:實時監(jiān)測網(wǎng)絡(luò)狀態(tài)的工具類。當(dāng)前的網(wǎng)絡(luò)環(huán)境發(fā)生改變之后,這個工具類就可以檢測到。
4). AFSecurityPolicy:網(wǎng)絡(luò)安全的工具類, 主要是針對 HTTPS 服務(wù)。

5). AFURLRequestSerialization:序列化工具類,基類。上傳的數(shù)據(jù)轉(zhuǎn)換成JSON格式
(AFJSONRequestSerializer).使用不多。
6). AFURLResponseSerialization:反序列化工具類;基類.使用比較多:
7). AFJSONResponseSerializer; JSON解析器,默認(rèn)的解析器.
8). AFHTTPResponseSerializer; 萬能解析器; JSON和XML之外的數(shù)據(jù)類型,直接返回二進
制數(shù)據(jù).對服務(wù)器返回的數(shù)據(jù)不做任何處理.
9). AFXMLParserResponseSerializer; XML解析器;

37.描述下SDWebImage里面給UIImageView加載圖片的邏輯

SDWebImage 中為 UIImageView 提供了一個分類UIImageView+WebCache.h, 這個分類中有一個最常用的接口sd_setImageWithURL:placeholderImage:,會在真實圖片出現(xiàn)前會先顯示占位圖片,當(dāng)真實圖片被加載出來后再替換占位圖片。

加載圖片的過程大致如下:
1.首先會在 SDWebImageCache 中尋找圖片是否有對應(yīng)的緩存, 它會以url 作為數(shù)據(jù)的索引先在內(nèi)存中尋找是否有對應(yīng)的緩存
2.如果緩存未找到就會利用通過MD5處理過的key來繼續(xù)在磁盤中查詢對應(yīng)的數(shù)據(jù), 如果找到了, 就會把磁盤中的數(shù)據(jù)加載到內(nèi)存中,并將圖片顯示出來
3.如果在內(nèi)存和磁盤緩存中都沒有找到,就會向遠程服務(wù)器發(fā)送請求,開始下載圖片
4.下載后的圖片會加入緩存中,并寫入磁盤中
5.整個獲取圖片的過程都是在子線程中執(zhí)行,獲取到圖片后回到主線程將圖片顯示出來

SDWebImage原理:
調(diào)用類別的方法:
1. 從內(nèi)存(字典)中找圖片(當(dāng)這個圖片在本次使用程序的過程中已經(jīng)被加載過),找到直接使用。
2. 從沙盒中找(當(dāng)這個圖片在之前使用程序的過程中被加載過),找到使用,緩存到內(nèi)存中。
3. 從網(wǎng)絡(luò)上獲取,使用,緩存到內(nèi)存,緩存到沙盒。

38.談?wù)?UITableView 的優(yōu)化
1). 正確的復(fù)用cell。
2). 設(shè)計統(tǒng)一規(guī)格的Cell
3). 提前計算并緩存好高度(布局),因為heightForRowAtIndexPath:是調(diào)用最頻繁的方法;
4). 異步繪制,遇到復(fù)雜界面,遇到性能瓶頸時,可能就是突破口;
4). 滑動時按需加載,這個在大量圖片展示,網(wǎng)絡(luò)加載的時候很管用!
5). 減少子視圖的層級關(guān)系
6). 盡量使所有的視圖不透明化以及做切圓操作。
7). 不要動態(tài)的add 或者 remove 子控件。最好在初始化時就添加完,然后通過hidden來控制是否顯示。
8). 使用調(diào)試工具分析問題。

39.如何實行cell的動態(tài)的行高

如果希望每條數(shù)據(jù)顯示自身的行高,必須設(shè)置兩個屬性,1.預(yù)估行高,2.自定義行高。
設(shè)置預(yù)估行高 tableView.estimatedRowHeight = 200。
設(shè)置定義行高 tableView.estimatedRowHeight = UITableViewAutomaticDimension。
如果要讓自定義行高有效,必須讓容器視圖有一個自下而上的約束。

40.什么是野指針、空指針?
野指針:不知道指向了哪里的指針叫野指針。即指針指向不確定,指針存的地址是一個垃圾值,未初始化。
空指針:不指向任何位置的指針叫空指針。即指針沒有指向,指針存的地址是一個空地址,NULL。

41.fmpeg框架:?ffmpeg 是音視頻處理工具,既有音視頻編碼解碼功能,又可以作為播放器使用。

42.什么是 OpenGL、Quartz 2D?
Quatarz 2d 是Apple提供的基本圖形工具庫。只是適用于2D圖形的繪制。
OpenGL,是一個跨平臺的圖形開發(fā)庫。適用于2D和3D圖形的繪制。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 設(shè)計模式是什么? 你知道哪些設(shè)計模式,并簡要敘述?設(shè)計模式是一種編碼經(jīng)驗,就是用比較成熟的邏輯去處理某一種類型的事...
    irenb閱讀 5,390評論 1 21
  • 設(shè)計模式是什么? 你知道哪些設(shè)計模式,并簡要敘述? 設(shè)計模式是一種編碼經(jīng)驗,就是用比較成熟的邏輯去處理某一種類型的...
    Jt_Self閱讀 836評論 0 4
  • 史上最全的iOS面試題及答案 iOS面試小貼士———————————————回答好下面的足夠了----------...
    Style_偉閱讀 2,580評論 0 35
  • iOS面試小貼士 ———————————————回答好下面的足夠了------------------------...
    不言不愛閱讀 2,255評論 0 7
  • 多線程、特別是NSOperation 和 GCD 的內(nèi)部原理。運行時機制的原理和運用場景。SDWebImage的原...
    LZM輪回閱讀 2,133評論 0 12

友情鏈接更多精彩內(nèi)容