iOS面試題必考問題

iOS面試必考問題

1巾腕、多態(tài)面睛、繼承、封裝

封裝:就是對類中的一些字段尊搬,方法進(jìn)行保護(hù)叁鉴,不被外界所訪問到,有一種權(quán)限的控制功能佛寿,四種訪問權(quán)限修飾符:public幌墓,default,protected冀泻,private常侣,訪問權(quán)限一次遞減的,這樣我們在定義類的時候弹渔,哪些字段和方法不想暴露出去胳施,哪些字段和方法可以暴露,可以通過修飾符來完成肢专,這就是封裝舞肆;

繼承:使得我們沒必要別寫重復(fù)的代碼,可重用性很高鸟召。缺點(diǎn):繼承提高了代碼的耦合性.優(yōu)點(diǎn): 提高復(fù)用性胆绊,維護(hù)性

多態(tài):定義類型和實(shí)際類型氨鹏,一般是基于接口的形式實(shí)現(xiàn)的

2欧募、代理模式、單例模式仆抵、觀察者模式跟继、工廠模式

代理這是iOS中一種消息傳遞的方式,也可以通過這種方式來傳遞一些參數(shù)
協(xié)議:用來指定代理雙方可以做什么镣丑,必須做什么舔糖。
代理:根據(jù)指定的協(xié)議,完成委托方需要實(shí)現(xiàn)的功能莺匠。
委托:根據(jù)指定的協(xié)議金吗,指定代理去完成什么功能。

協(xié)議是什么?有什么作用?
協(xié)議:聲明一系列的方法趣竣,可由任何類實(shí)施摇庙,即使遵守該協(xié)議的類沒有共同的超類。協(xié)議方法定義了獨(dú)立于任何特定類的行為遥缕。簡單的說卫袒,協(xié)議就是定義了一個接口,其他類負(fù)責(zé)來實(shí)現(xiàn)這些接口单匣。如果你的類實(shí)現(xiàn)了一個協(xié)議的方法時夕凝,則說該類遵循此協(xié)議宝穗。
協(xié)議的作用:
1.定義一套公用的接口(Public)
@required:必須實(shí)現(xiàn)的方法
@optional:可選實(shí)現(xiàn)的方法(可以全部都不實(shí)現(xiàn))
2.委托代理(Delegate)傳值:
它本身是一個設(shè)計模式,它的意思是委托別人去做某事码秉。
比如:兩個類之間的傳值逮矛,類A調(diào)用類B的方法,類B在執(zhí)行過程中遇到問題通知類A转砖,這時候我們需要用到代理(Delegate)橱鹏。

單例:確保某一個類只有一個實(shí)例,而且自行實(shí)例化并向整個系統(tǒng)提供整個實(shí)例堪藐。
優(yōu)點(diǎn):
1莉兰、減少內(nèi)存開支和系統(tǒng)性能開銷;
2礁竞、避免對資源的多重占用糖荒;
3、優(yōu)化和共享資源訪問模捂。
缺點(diǎn):
1捶朵、單例模式?jīng)]有接口,擴(kuò)展很困難狂男;
2综看、單例模式與單一職責(zé)有沖突。
通過GCD實(shí)現(xiàn)單例方法:

 (.h文件中)
+(DBManager *)sharedManager;   
.m文件中的實(shí)現(xiàn):
+(DBManager *)sharedManager{
 Static DBManager *manager = nil;
  static dispatch_once_t token;
  dispatch_once(&token,^{
         if(manager == nil){
           manager = [[DBManager alloc]init];
   }
} );
return manager;
}

3岖食、事件響應(yīng)連

hit-Testing:找出這個觸摸點(diǎn)下面的hit-test view的過程红碑,HitTest會檢測這個點(diǎn)擊的點(diǎn)是不是發(fā)生在這個View上,如果是的話泡垃,就會去遍歷這個View的subviews析珊,直到找到最小的能夠處理事件的view,如果整了一圈沒找到能夠處理的view蔑穴,則返回自身忠寻。

 - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
 //該方法的處理過程:
 //首先調(diào)用當(dāng)前視圖的pointInside:withEvent:方法判斷觸摸點(diǎn)是否在當(dāng)前視圖內(nèi);
 //YES在,則遍歷當(dāng)前視圖的所有子視圖(subviews)存和,調(diào)用子視圖的hitTest:withEvent:奕剃;
 // NO不在,當(dāng)前視圖的hitTest:withEvent:返回nil
 //若第一次有子視圖的hitTest:withEvent:方法返回非空對象,則當(dāng)前視圖的hitTest:withEvent:方法就返回此對象捐腿,處理結(jié)束
 //若所有子視圖的hitTest:withEvent:方法都返回nil纵朋,則當(dāng)前視圖的hitTest:withEvent:方法返回當(dāng)前視圖自身(self)

//判斷觸摸點(diǎn)是否在當(dāng)前視圖內(nèi),可以用來實(shí)現(xiàn)擴(kuò)大View的相應(yīng)區(qū)域
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;

1.事件的產(chǎn)生
發(fā)生觸摸事件后叙量,系統(tǒng)會將該事件加入到一個由UIApplication管理的事件隊列中為什么是隊列而不是棧倡蝙?因?yàn)殛犃械奶囟ㄊ窍冗M(jìn)先出,先產(chǎn)生的事件先處理才符合常理绞佩,所以把事件添加到隊列寺鸥。
UIApplication會從事件隊列中取出最前面的事件猪钮,并將事件分發(fā)下去以便處理,通常胆建,先發(fā)送事件給應(yīng)用程序的主窗口(keyWindow)烤低。
主窗口會在視圖層次結(jié)構(gòu)中找到一個最合適的視圖來處理觸摸事件,這也是整個事件處理過程的第一步笆载。
找到合適的視圖控件后扑馁,就會調(diào)用視圖控件的touches方法來作具體的事件處理。
2.事件的傳遞
觸摸事件的傳遞是從父控件傳遞到子控件
也就是UIApplication->window->尋找處理事件最合適的view

4凉驻、NSThread腻要、NSOperation、GCD

什么是進(jìn)程
a涝登、是指在系統(tǒng)中正在運(yùn)行的一個應(yīng)用程序雄家;
b、每個進(jìn)程之間是獨(dú)立的胀滚,每個進(jìn)程運(yùn)行在其專用且受保護(hù)的內(nèi)存空間趟济;
什么是線程
a、一個進(jìn)程想要執(zhí)行任務(wù)咽笼,必須得有線程(每個進(jìn)程至少要有一條線程)顷编;
b、線程是進(jìn)程的基本執(zhí)行單元剑刑,一個進(jìn)程(程序)的所有任務(wù)都在線程中執(zhí)行媳纬;

5、MVC叛甫、MVVM等 View層架構(gòu)模式

6层宫、NSUserDefault杨伙、Plist其监、NSCode、Sqlite限匣、CoreData抖苦、File

plist文件(屬性列表)

preference(偏好設(shè)置)

NSKeyedArchiver(歸檔)

SQLite 3

CoreData (icloud 無主鍵)

7、delegate米死、Notification锌历、block

block本質(zhì)是一個數(shù)據(jù)類型,多用于參數(shù)傳遞,代替代理方法, (有多個參數(shù)需要傳遞或者多個代理方法需要實(shí)現(xiàn)還是推薦使用代理方法),少用于當(dāng)做返回值傳遞. block是一個OC對象,它的功能是保存代碼片段,預(yù)先準(zhǔn)備好代碼,并在需要的時候執(zhí)行.

8、內(nèi)存管理峦筒、內(nèi)存優(yōu)化究西、內(nèi)存泄漏

自動釋放池@autoreleasepool

自動釋放池底層怎么實(shí)現(xiàn)

自動釋放池以棧的形式實(shí)現(xiàn):當(dāng)你創(chuàng)建一個新的自動釋放池時,它將被添加到棧頂物喷。當(dāng)一個對象收到發(fā)送autorelease消息時,它被添加到當(dāng)前線程的處于棧頂?shù)淖詣俞尫懦刂?當(dāng)自動釋放池被回收時,它們從棧中被刪除,并且會給池子里面所有的對象都會做一次release操作.

OC對象的生命周期取決于引用計數(shù)卤材,我們有兩種方式可以釋放對象:一種是直接調(diào)用release釋放遮斥;另一種是調(diào)用autorelease將對象加入自動釋放池中。自動釋放池用于存放那些需要在稍后某個時刻釋放的對象扇丛。

我們的Mac以及iOS系統(tǒng)會自動創(chuàng)建一些線程术吗,例如主線程和GCD中的線程,都默認(rèn)擁有自動釋放池帆精。每次執(zhí)行 “事件循環(huán)”(event loop)時较屿,就會將其清空,這一點(diǎn)非常重要卓练,請務(wù)必牢記隘蝎!

9、堆和棧

棧襟企,是由系統(tǒng)編譯器自動管理末贾,不需要程序員手動管理,存放方法(函數(shù))的參數(shù)值整吆,局部變量的值等拱撵,棧是向低地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu),是一塊連續(xù)的內(nèi)存區(qū)域
堆表蝙,釋放工作由程序員手動管理拴测,不及時回收容易產(chǎn)生內(nèi)存泄露,堆是向高地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu)府蛇,是不連續(xù)的內(nèi)存區(qū)域集索。這是由于系統(tǒng)是用鏈表來存儲的空閑內(nèi)存地址的,自然是不連續(xù)的汇跨,而鏈表的遍歷方向是由低地址向高地址务荆。堆的大小受限于計算機(jī)系統(tǒng)中有效的虛擬內(nèi)存。由此可見穷遂,堆獲得的空間比較靈活函匕,也比較大。

棧區(qū)存放局部變量蚪黑,先進(jìn)后出盅惜,當(dāng)程序執(zhí)行出了作用于的范圍,棧區(qū)局部變量就會被銷毀忌穿,所以我們也不需要管理棧區(qū)的內(nèi)存抒寂。
1.在iOS中,堆區(qū)的內(nèi)存是所有應(yīng)用程序共享的

2.堆區(qū)內(nèi)存分配是由系統(tǒng)來負(fù)責(zé)的

3.系統(tǒng)通過鏈表來維護(hù)所有已經(jīng)分配過的內(nèi)存空間

4.系統(tǒng)只是記錄分配了多少字節(jié)給應(yīng)用程序掠剑,但是并不管理具體分配給的對象類型

5.變量使用結(jié)束后屈芜,需要釋放內(nèi)存。在OC中當(dāng)retainCount == 0時朴译,就說明沒有任何變量使用該空間井佑,那么系統(tǒng)就會直接回收

6.如果我們使用某一個變量之后糕珊,不釋放內(nèi)存,那么該內(nèi)存就會被永遠(yuǎn)占用毅糟,造成內(nèi)存泄漏

7.當(dāng)對象已經(jīng)釋放红选,但是程序中的變量仍然指向該內(nèi)存地址,這個時候姆另,如果向該對象發(fā)送消息喇肋,就會出現(xiàn)經(jīng)典的野指針錯誤

10、const迹辐、static蝶防、extern

11、readwrite ,readonly strong明吩,weak间学,retain,assign印荔,copy , nonatomic , natomic

readwrite : 是可讀可寫屬性低葫,需要生成setter 和 getter 方法;
readonly: 是可讀屬性,只生成getter方法仍律,不生成setter方法嘿悬,不希望屬性再類外改變;
strong:
weak:
retain: 表示持有特性水泉,setter方法將傳入的參數(shù)保留善涨,再賦值,傳入?yún)?shù)引用計數(shù)retaincount + 1草则;
assign: 是賦值特性钢拧,setter方法將傳入的參數(shù)賦值給實(shí)體變量,僅設(shè)置變量時炕横,assign用于簡單數(shù)據(jù)類型 如 NSInterger ,double ,float ,bool
copy: 表示賦值特性源内,setter方式將傳入的對象復(fù)制一份,需完全復(fù)制一份新的變量時:
noatomic: 非原子性操作看锉,決定編譯器生成的setter和getter 方法是否是原子性的操作姿锭;
atomic: 表示多線程安全

12、documents伯铣,tmp,app轮纫,Library

14腔寡、category、extension(類擴(kuò)展)

類別:Category 是表示一個指向分類的結(jié)構(gòu)體的指針掌唾。
1.分類是用于給原有類添加方法的,因?yàn)榉诸惖慕Y(jié)構(gòu)體指針中放前,沒有屬性列表忿磅,只有方法列表。所以< 原則上講它只能添加方法, 不能添加屬性(成員變量),實(shí)際上可以通過其它方式添加屬性> ;
2.分類中的可以寫@property, 但不會生成setter/getter方法, 也不會生成實(shí)現(xiàn)以及私有的成員變量(編譯時會報警告);
3.可以在分類中訪問原有類中.h中的屬性;
4.如果分類中有和原有類同名的方法, 會優(yōu)先調(diào)用分類中的方法, 就是說會忽略原有類的方法凭语。所以同名方法調(diào)用的優(yōu)先級為 分類 > 本類 > 父類葱她。因此在開發(fā)中盡量不要覆蓋原有類;
5.如果多個分類中都有和原有類中同名的方法, 那么調(diào)用該方法的時候執(zhí)行誰由編譯器決定;編譯器會執(zhí)行最后一個參與編譯的分類中的方法似扔。


擴(kuò)展:

  1. 能為某個類添加成員變量,屬性,方法;
  2. 一般的類擴(kuò)展寫到.m文件中;
  3. 一般的私有屬性寫到類擴(kuò)展中

區(qū)別:

①類別中原則上只能增加方法(能添加屬性的的原因只是通過runtime解決無setter/getter的問題而已)吨些;
②類擴(kuò)展不僅可以增加方法,還可以增加實(shí)例變量(或者屬性)炒辉,只是該實(shí)例變量默認(rèn)是@private類型的(
用范圍只能在自身類豪墅,而不是子類或其他地方);
③類擴(kuò)展中聲明的方法沒被實(shí)現(xiàn)黔寇,編譯器會報警偶器,但是類別中的方法沒被實(shí)現(xiàn)編譯器是不會有任何警告的。這是因?yàn)轭悢U(kuò)展是在編譯階段被添加到類中缝裤,而類別是在運(yùn)行時添加到類中屏轰。
④類擴(kuò)展不能像類別那樣擁有獨(dú)立的實(shí)現(xiàn)部分(@implementation部分),也就是說憋飞,類擴(kuò)展所聲明的方法必須依托對應(yīng)類的實(shí)現(xiàn)部分來實(shí)現(xiàn)亭枷。
⑤定義在 .m 文件中的類擴(kuò)展方法為私有的,定義在 .h 文件(頭文件)中的類擴(kuò)展方法為公有的搀崭。類擴(kuò)展是在 .m 文件中聲明私有方法的非常好的方式叨粘。

15、KVO瘤睹、KVC

KVC的本質(zhì)就是 (鍵值編碼)

定義: 在對象創(chuàng)建完成之后,動態(tài)(牽扯到運(yùn)行時)的給對象的屬性賦值
KVO 的本質(zhì)就是(鍵值監(jiān)聽)

定義::Key-Value Observing,它提供一種機(jī)制,當(dāng)指定的對象的屬性被修改后,則對象就會接受到通知升敲。

KVO是基于KVC實(shí)現(xiàn)的,只有我們調(diào)用KVC去訪問key值的時候KVO才會起作用轰传。

KVO只用來監(jiān)聽屬性值的變化驴党,這個發(fā)送監(jiān)聽的操作是系統(tǒng)控制的,我們控制不了获茬,我們只能控制監(jiān)聽操作
通知需要一個發(fā)送notification的對象港庄,一般是notificationCenter,來通知觀察者恕曲。KVO是直接通知到觀察對象鹏氧,并且邏輯非常清晰,實(shí)現(xiàn)步驟簡單佩谣。
通知需要一個發(fā)送notification的對象把还,一般是notificationCenter,來通知觀察者。KVO是直接通知到觀察對象吊履,并且邏輯非常清晰安皱,實(shí)現(xiàn)步驟簡單。

16艇炎、runtime

17酌伊、runloop

指導(dǎo)文章:http://www.swiftyper.com/2017/01/04/runloop-learning-note/

RunLoop 是一種事件驅(qū)動(Event Driven)模型,
但是一個 iOS 應(yīng)用一旦啟動起來后就會一直處于等待用戶事件(類似點(diǎn)擊或者觸摸事件)的狀態(tài)缀踪,除非用戶手動關(guān)閉它居砖,
當(dāng)我們使用 Xcode 創(chuàng)建一個新的 iOS 應(yīng)用時,它會自動幫我們生成 main 方法(這個方法在 main.m 文件中)辜贵,而在 main 方法里面會調(diào)用 UIApplicationMain 方法悯蝉。UIApplicationMain 會將 AppDelegate 設(shè)置為應(yīng)用程序的代碼,同時會為主線程創(chuàng)建一個 RunLoop 并啟動托慨,因此任何一個 iOS 應(yīng)用一旦啟動了鼻由,就至少存在一個 RunLoop,并且這個 RunLoop 是屬于主線程的厚棵。之所以說屬于主線程蕉世,是因?yàn)?RunLoop 與線程的關(guān)系是一一對應(yīng)的。

其實(shí)事件驅(qū)動模型的本質(zhì)就是一個死循環(huán)婆硬,然后在循環(huán)中不斷等待消息的到來狠轻,然后對其進(jìn)行處理,
RunLoop 實(shí)際上就是一個對象彬犯,它為我們提供了一個進(jìn)入事件循環(huán)的入口函數(shù)向楼,線程執(zhí)行這個函數(shù)后就會處于消息循環(huán)中,直到循環(huán)結(jié)束(比如接收到退出消息)谐区。

在 iOS 中提供了兩個 RunLoop 對象:NSRunLoop 與 CFRunLoopRef湖蜕。

其中,NSRunLoop 是基于 CFRunLoopRef 的簡單封裝宋列。NSRunLoop 的 API 是非線程安全的昭抒,而 CFRunLoopRef 的 API 是線程安全的。更重要的一點(diǎn)是 CFRunLoopRef 的代碼是開源的炼杖。

特點(diǎn):1灭返、使程序一直運(yùn)行接收用戶輸入
2、決定程序何時處理哪些Event
3坤邪、調(diào)用解耦
4熙含、節(jié)省cpu

NSDefaulRunLoopMode (默認(rèn)狀態(tài),空閑狀態(tài))
NSTrackingRunLoopMode (滑動scrollView)
NSRunLoopCommonMode (上方兩著都可執(zhí)行)
列子: 當(dāng)列表滑動的時候罩扇,NSTime 不會動婆芦。
解答: 因NSTime處于DefaulRunLoopMode,當(dāng)滑動工程被切換到了TrackingRunLoopMode去關(guān)注滑動事件了,所以我們要將time設(shè)置為NSRunLoopCommonMode 

一個TableView延時加載圖片的新思路
在cell里面把設(shè)置圖片在 NSDefaulRunLoopMode中做怕磨,其滑動過程就不會設(shè)置圖片喂饥,

18消约、View層架構(gòu)、網(wǎng)絡(luò)層架構(gòu)员帮、持久層架構(gòu)或粮、組件化架構(gòu)、動態(tài)部署方案

19捞高、UITableView的優(yōu)化

20氯材、二叉樹、時間復(fù)雜度

21硝岗、TCP,UDP,HTTP

TCP也就是傳輸控制協(xié)議氢哮。它是一種面向連接的、可靠的型檀、基于字節(jié)流的[傳輸層]通信協(xié)議冗尤。主要解決數(shù)據(jù)如何在網(wǎng)絡(luò)中如何傳輸?shù)模且环N長連接胀溺。建立一個TCP連接需要有三次握手裂七,而終止一個TCP連接需要有4次握手,這是由TCP的半關(guān)閉(half-close)造成的仓坞。TCP包頭的最小長度為20字節(jié)背零。大小不受限制,是可靠協(xié)議无埃,安全送達(dá)

UDP也就是用戶數(shù)據(jù)報協(xié)議徙瓶。它與TCP相對應(yīng),是一種面向無連接的嫉称、不可靠的數(shù)據(jù)報傳輸協(xié)議侦镇,即不與對方建立連接,就直接就把數(shù)據(jù)包發(fā)送過去澎埠,因此缺乏可靠性虽缕。由于缺乏可靠性,UDP應(yīng)用一般必須允許一定量的丟包蒲稳、出錯和復(fù)制氮趋。大小限制在64k之內(nèi)無需連接,所以不可靠協(xié)議江耀,但速度快

HTTP也就是超文本傳輸協(xié)議剩胁。HTTP是Web聯(lián)網(wǎng)的基礎(chǔ),也是手機(jī)聯(lián)網(wǎng)常用的協(xié)議之一祥国,HTTP協(xié)議是建立在TCP協(xié)議之上的一種應(yīng)用昵观。HTTP連接最顯著的特點(diǎn)是客戶端發(fā)送的每次請求都需要服務(wù)器回送響應(yīng)晾腔,在請求結(jié)束后,會主動釋放連接啊犬。從建立連接到關(guān)閉連接的過程稱為“一次連接”灼擂。

TCP與UDP的區(qū)別

(1)TCP是需要連接的傳輸協(xié)議(長連接),UDP是不需要連接的傳輸協(xié)議觉至;
(2)TCP對系統(tǒng)資源要求較多剔应,UDP要求較少;
(3)TCP的程序結(jié)構(gòu)較復(fù)雜语御,UDP程序結(jié)構(gòu)較簡單峻贮;
(4)TCP是流模式,UDP是數(shù)據(jù)報模式 应闯;
(5)TCP保證數(shù)據(jù)正確性纤控,UDP可能丟包,TCP保證數(shù)據(jù)順序碉纺,UDP不保證船万。

第三方庫實(shí)現(xiàn)原理解析:

SDWebImage 如何為 UIImageView 添加圖片(面試回答)

SDWebImage 中為 UIView 提供了一個分類叫做 WebCache, 這個分類中有一個最常用的接口, sd_setImageWithURL:placeholderImage:, 這個分類同時提供了很多類似的方法, 這些方法最終會調(diào)用一個同時具有 option progressBlock completionBlock 的方法, 而在這個類最終被調(diào)用的方法首先會檢查是否傳入了 placeholderImage 以及對應(yīng)的參數(shù), 并設(shè)置 placeholderImage.

然后會獲取 SDWebImageManager 中的單例調(diào)用一個 downloadImageWithURL:... 的方法來獲取圖片, 而這個 manager 獲取圖片的過程有大體上分為兩部分, 它首先會在 SDWebImageCache 中尋找圖片是否有對應(yīng)的緩存, 它會以 url 作為數(shù)據(jù)的索引先在內(nèi)存中尋找是否有對應(yīng)的緩存, 如果緩存未命中就會在磁盤中利用 MD5 處理過的 key 來繼續(xù)查詢對應(yīng)的數(shù)據(jù), 如果找到了, 就會把磁盤中的緩存?zhèn)浞莸絻?nèi)存中.

然而, 假設(shè)我們在內(nèi)存和磁盤緩存中都沒有命中, 那么 manager 就會調(diào)用它持有的一個 SDWebImageDownloader 對象的方法 downloadImageWithURL:... 來下載圖片, 這個方法會在執(zhí)行的過程中調(diào)用另一個方法 addProgressCallback:andCompletedBlock:forURL:createCallback: 來存儲下載過程中和下載完成的回調(diào), 當(dāng)回調(diào)塊是第一次添加的時候, 方法會實(shí)例化一個 NSMutableURLRequest 和 SDWebImageDownloaderOperation, 并將后者加入 downloader 持有的下載隊列開始圖片的異步下載.

而在圖片下載完成之后, 就會在主線程設(shè)置 image 屬性, 完成整個圖像的異步下載和配置.

總結(jié)SDWebImage 的圖片加載過程其實(shí)很符合我們的直覺:
查看緩存
緩存命中
返回圖片
更新 UIImageView
緩存未命中
異步下載圖片
加入緩存
更新 UIImageView

UITableView重用cell

UITableViewCell的復(fù)用機(jī)制是,在tableview中存在一個復(fù)用池.這個復(fù)用池是一個隊列或一個鏈表.然后通過dequeueReusableCellWithIdentifier:獲取一個cell,如果當(dāng)前cell不存在,即新建一個cell,并將當(dāng)前cell添加進(jìn)復(fù)用池中.如果當(dāng)前的cell數(shù)量已經(jīng)到過tableview所能容納的個數(shù),則會在滾動到下一個cell時,自動取出之前的cell并設(shè)置內(nèi)容.

排序算法

冒泡排序

NSMutableArray *arr_M = [NSMutableArray arrayWithObjects:@1,@4,@2,@3,@5,nil];
    //遍歷`數(shù)組的個數(shù)`次
    /*
     i = 0 的時候,j的相鄰兩個位置都要比較排一下位置:
         j = 0 的時候:arr_M = 41235
         j = 1 的時候:arr_M = 42135
         j = 2 的時候:arr_M = 42315
         j = 3 的時候:arr_M = 42351
     i = 1;
      ……  ……
     */
    for (int i = 0; i < arr_M.count; ++i) {

        //遍歷數(shù)組的每一個`索引`(不包括最后一個,因?yàn)楸容^的是j+1)
        for (int j = 0; j < arr_M.count-1; ++j) {
            //根據(jù)索引的`相鄰兩位`進(jìn)行`比較`
            if (arr_M[j] < arr_M[j+1]) {
                [arr_M exchangeObjectAtIndex:j withObjectAtIndex:j+1];
            }
        }
    }
    NSLog(@"最終結(jié)果:%@",arr_M);

選擇排序

NSMutableArray *arr_M = [NSMutableArray arrayWithObjects:@1,@4,@2,@3,@5,nil];

    for (int i=0; i<arr_M.count; i++) {

        for (int j=i+1; j<arr_M.count; j++) {

            if (arr_M[i]<arr_M[j]) {

                [arr_M exchangeObjectAtIndex:i withObjectAtIndex:j];

            }

        }
    }
    NSLog(@"%@",arr_M);

copy與mutableCopy 深復(fù)制和淺復(fù)制

copy 拷貝的對象為不可修改的惜辑,而mutableCopy拷貝的對象為可改變的對象唬涧,即使被復(fù)制的對象本身為不可改變的,調(diào)用mutableCopy方法復(fù)制出來的副本也是可修改的盛撑,當(dāng)程序調(diào)用對象的copy方法來復(fù)制自身時碎节,底層需要調(diào)用copyWithZone:方法來完成實(shí)際的復(fù)制工作,copy返回實(shí)際上就是copyWithZone:方法的返回值抵卫;mutableCopy與mutableCopyWithZone:方法也是同樣的道理狮荔。

淺復(fù)制和深復(fù)制:顧名思義,淺復(fù)制介粘,并不拷貝對象本身殖氏,僅僅是拷貝指向?qū)ο蟮闹羔槪簧顝?fù)制是直接拷貝整個對象內(nèi)容到另一塊內(nèi)存中姻采。再簡單些說:淺復(fù)制就是指針拷貝雅采;深復(fù)制就是內(nèi)容拷貝。

AsyncSocket

考慮到數(shù)據(jù)量比較大的問題慨亲,所以數(shù)據(jù)大的時候我會使用分包和組包的功能去實(shí)現(xiàn)婚瓜。TCP/IP在傳輸數(shù)據(jù)的時候,一般不會大于1500字節(jié)刑棵,所以我每512字節(jié)分了

一個包巴刻。然后當(dāng)一次性數(shù)據(jù)包接收太多的時候,就出現(xiàn)了粘包的問題蛉签。因?yàn)槲以跀?shù)據(jù)傳輸?shù)臅r候使用的是json胡陪,每一個分包都是由{}括起來的沥寥,所以我就想著在包頭上加上一段基本不會重復(fù)

的分割字符串,然后服務(wù)器接收到分包的時候每次都根據(jù)這個字符串分割一下柠座,第一次分割的時候第一行絕對是空字符串 例如:@Hinagiku{“Name”=“桂雛菊”}邑雅, 我分割出來結(jié)果是:

“”,“桂雛菊”愚隧,所以說第一行我就可以直接跳過蒂阱,每次取分包的時候從第二行開始取锻全。然后后臺根據(jù)包的ID號狂塘,序號進(jìn)行組包。如果當(dāng)前分包在5分鐘內(nèi)沒有接收完畢鳄厌,就代表當(dāng)前分包接收失敗

了荞胡,要求客戶端或服務(wù)器重新發(fā)送。粘包問題解決完畢之后了嚎,我開始實(shí)現(xiàn)心跳包功能勉吻,當(dāng)時想的是幽污,每隔1分鐘發(fā)一次心跳包,服務(wù)器放一個線程。每隔幾秒鐘判斷一次迫淹,當(dāng)前的所有TCP連接的
最后一次訪問時間是多少號,如果超過了這個時間則斷開當(dāng)前連接

tag參數(shù)是為了在回調(diào)方法中匹配發(fā)起調(diào)用的方法的颈渊,不會加在傳輸數(shù)據(jù)中瘟檩。
需注意的一點(diǎn)是:發(fā)送時的tag和接收時的tag是無關(guān)的。
以read為例分析:

  • (void)readDataWithTimeout:(NSTimeInterval)timeout tag:(long)tag
    上面的方法會生成一個數(shù)據(jù)類:AsyncReadPacket伶氢,此類中包含tag趟径,并把此對象放入數(shù)組theReadQueue中。
    在CFStream中的回調(diào)方法中癣防,會取theReadQueue最新的一個蜗巧,在回調(diào)方法中取得tag,并將tag傳
    給回調(diào)方法:
  • (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag;
    如此而已
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蕾盯,一起剝皮案震驚了整個濱河市幕屹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌级遭,老刑警劉巖望拖,帶你破解...
    沈念sama閱讀 218,451評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異装畅,居然都是意外死亡靠娱,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評論 3 394
  • 文/潘曉璐 我一進(jìn)店門掠兄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來像云,“玉大人锌雀,你說我怎么就攤上這事⊙肝埽” “怎么了腋逆?”我有些...
    開封第一講書人閱讀 164,782評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長侈贷。 經(jīng)常有香客問我惩歉,道長,這世上最難降的妖魔是什么俏蛮? 我笑而不...
    開封第一講書人閱讀 58,709評論 1 294
  • 正文 為了忘掉前任撑蚌,我火速辦了婚禮,結(jié)果婚禮上搏屑,老公的妹妹穿的比我還像新娘争涌。我一直安慰自己,他們只是感情好辣恋,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評論 6 392
  • 文/花漫 我一把揭開白布亮垫。 她就那樣靜靜地躺著,像睡著了一般伟骨。 火紅的嫁衣襯著肌膚如雪饮潦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,578評論 1 305
  • 那天携狭,我揣著相機(jī)與錄音继蜡,去河邊找鬼。 笑死暑中,一個胖子當(dāng)著我的面吹牛壹瘟,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鳄逾,決...
    沈念sama閱讀 40,320評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼稻轨,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了雕凹?” 一聲冷哼從身側(cè)響起殴俱,我...
    開封第一講書人閱讀 39,241評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎枚抵,沒想到半個月后线欲,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,686評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡汽摹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評論 3 336
  • 正文 我和宋清朗相戀三年李丰,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片逼泣。...
    茶點(diǎn)故事閱讀 39,992評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡趴泌,死狀恐怖舟舒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情嗜憔,我是刑警寧澤秃励,帶...
    沈念sama閱讀 35,715評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站吉捶,受9級特大地震影響夺鲜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜呐舔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評論 3 330
  • 文/蒙蒙 一币励、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧滋早,春花似錦榄审、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽浪感。三九已至昔头,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間影兽,已是汗流浹背揭斧。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留峻堰,地道東北人讹开。 一個月前我還...
    沈念sama閱讀 48,173評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像捐名,于是被迫代替她去往敵國和親旦万。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 從三月份找實(shí)習(xí)到現(xiàn)在镶蹋,面了一些公司成艘,掛了不少,但最終還是拿到小米贺归、百度淆两、阿里、京東拂酣、新浪秋冰、CVTE、樂視家的研發(fā)崗...
    時芥藍(lán)閱讀 42,248評論 11 349
  • *面試心聲:其實(shí)這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,143評論 30 470
  • iOS面試小貼士 ———————————————回答好下面的足夠了------------------------...
    不言不愛閱讀 1,980評論 0 7
  • 史上最全的iOS面試題及答案 iOS面試小貼士———————————————回答好下面的足夠了----------...
    Style_偉閱讀 2,356評論 0 35
  • “我要吃這個甥材,還有這個…”望著手里堆成山的食盤盯另,陳翕回頭沖著秦灼于眨了個眼,發(fā)出了“求救”信號洲赵。像高中與世隔絕的小...
    Ooooyho閱讀 197評論 0 0