2017最新iOS面試題

設計模式是什么角虫? 你知道哪些設計模式,并簡要敘述殴胧?

設計模式是一種編碼經(jīng)驗渗稍,就是用比較成熟的邏輯去處理某一種類型的事情。 1). MVC模式:Model View Control团滥,把模型 視圖 控制器 層進行解耦合編寫竿屹。 2). MVVM模式:Model View ViewModel 把模型 視圖 業(yè)務邏輯 層進行解耦和編寫。 3). 單例模式:通過static關鍵詞灸姊,聲明全局變量拱燃。在整個進程運行期間只會被賦值一次。 4). 觀察者模式:KVO是典型的通知模式力惯,觀察某個屬性的狀態(tài)碗誉,狀態(tài)發(fā)生變化時通知觀察者。 5). 委托模式:代理+協(xié)議的組合父晶。實現(xiàn)1對1的反向傳值操作哮缺。 6). 工廠模式:通過一個類方法,批量的根據(jù)已有模板生產(chǎn)對象甲喝。 MVC 和 MVVM 的區(qū)別

1). MVVM是對胖模型進行的拆分尝苇,其本質(zhì)是給控制器減負,將一些弱業(yè)務邏輯放到VM中去處理。 2). MVC是一切設計的基礎糠溜,所有新的設計模式都是基于MVC進行的改進淳玩。

import跟 #include 有什么區(qū)別,@class呢非竿,#import<> 跟 #import””有什么區(qū)別凯肋?

答: 1). #import是Objective-C導入頭文件的關鍵字,#include是C/C++導入頭文件的關鍵字汽馋,使用#import頭文件會自動只導入一次侮东,不會重復導入。 2). @class告訴編譯器某個類的聲明豹芯,當執(zhí)行時悄雅,才去查看類的實現(xiàn)文件,可以解決頭文件的相互包含铁蹈。 3). #import<>用來包含系統(tǒng)的頭文件宽闲,#import””用來包含用戶頭文件。

frame 和 bounds 有什么不同握牧?

frame指的是:該view在父view坐標系統(tǒng)中的位置和大小容诬。(參照點是父view的坐標系統(tǒng)) bounds指的是:該view在本身坐標系統(tǒng)中的位置和大小。(參照點是本身坐標系統(tǒng))

Objective-C的類可以多重繼承么沿腰?可以實現(xiàn)多個接口么览徒?Category是什么?重寫一個類的方式用繼承好還是分類好颂龙?為什么习蓬?

答:Objective-C的類不可以多重繼承;可以實現(xiàn)多個接口(協(xié)議)措嵌;Category是類別躲叼;一般情況用分類好,用Category去重寫類的方法企巢,僅對本Category有效枫慷,不會影響到其他類與原有類的關系。

@property 的本質(zhì)是什么浪规?ivar或听、getter、setter 是如何生成并添加到這個類中的

@property 的本質(zhì)是什么罗丰? @property = ivar + getter + setter; “屬性” (property)有兩大概念:ivar(實例變量)神帅、getter+setter(存取方法)

“屬性” (property)作為 Objective-C 的一項特性再姑,主要的作用就在于封裝對象中的數(shù)據(jù)萌抵。 Objective-C 對象通常會把其所需要的數(shù)據(jù)保存為各種實例變量。實例變量一般通過“存取方法”(access method)來訪問。其中绍填,“獲取方法” (getter)用于讀取變量值霎桅,而“設置方法” (setter)用于寫入變量值。

@property中有哪些屬性關鍵字讨永?/ @property 后面可以有哪些修飾符滔驶?

屬性可以擁有的特質(zhì)分為四類: 1.原子性--- nonatomic 特質(zhì) 2.讀/寫權(quán)限---readwrite(讀寫)、readonly (只讀) 3.內(nèi)存管理語義---assign卿闹、strong揭糕、 weak、unsafe_unretained锻霎、copy 4.方法名---getter=著角、setter=5.不常用的:nonnull,null_resettable,nullable

屬性關鍵字 readwrite,readonly旋恼,assign吏口,retain,copy冰更,nonatomic 各是什么作用产徊,在那種情況下用?

答: 1). readwrite 是可讀可寫特性蜀细。需要生成getter方法和setter方法舟铜。 2). readonly 是只讀特性。只會生成getter方法奠衔,不會生成setter方法深滚,不希望屬性在類外改變。 3). assign 是賦值特性涣觉。setter方法將傳入?yún)?shù)賦值給實例變量;僅設置變量時,assign用于基本數(shù)據(jù)類型痴荐。 4). retain(MRC)/strong(ARC) 表示持有特性。setter方法將傳入?yún)?shù)先保留官册,再賦值生兆,傳入?yún)?shù)的retaincount會+1。 5). copy 表示拷貝特性膝宁。setter方法將傳入對象復制一份鸦难,需要完全一份新的變量時。 6). nonatomic 非原子操作员淫。決定編譯器生成的setter和getter方法是否是原子操作合蔽,atomic表示多線程安全,一般使用nonatomic介返,效率高拴事。

什么情況使用 weak 關鍵字沃斤,相比 assign 有什么不同?

1.在 ARC 中,在有可能出現(xiàn)循環(huán)引用的時候,往往要通過讓其中一端使用 weak 來解決,比如: delegate 代理屬性刃宵。 2.自身已經(jīng)對它進行一次強引用,沒有必要再強引用一次,此時也會使用 weak,自定義 IBOutlet 控件屬性一般也使用 weak衡瓶;當然,也可以使用strong牲证。

IBOutlet連出來的視圖屬性為什么可以被設置成weak? 因為父控件的subViews數(shù)組已經(jīng)對它有一個強引用哮针。

不同點: assign 可以用非 OC 對象,而 weak 必須用于 OC 對象坦袍。 weak 表明該屬性定義了一種“非擁有關系”十厢。在屬性所指的對象銷毀時,屬性值會自動清空(nil)捂齐。

怎么用 copy 關鍵字寿烟?

用途:

NSString、NSArray辛燥、NSDictionary 等等經(jīng)常使用copy關鍵字筛武,是因為他們有對應的可變類型:NSMutableString、NSMutableArray挎塌、NSMutableDictionary徘六;

block 也經(jīng)常使用 copy 關鍵字。

說明: block 使用 copy 是從 MRC 遺留下來的“傳統(tǒng)”,在 MRC 中,方法內(nèi)部的 block 是在棧區(qū)的,使用 copy 可以把它放到堆區(qū).在 ARC 中寫不寫都行:對于 block 使用 copy 還是 strong 效果是一樣的榴都,但寫上 copy 也無傷大雅待锈,還能時刻提醒我們:編譯器自動對 block 進行了 copy 操作。如果不寫 copy 嘴高,該類的調(diào)用者有可能會忘記或者根本不知道“編譯器會自動對 block 進行了 copy 操作”竿音,他們有可能會在調(diào)用之前自行拷貝屬性值。這種操作多余而低效拴驮。

用@property聲明的 NSString / NSArray / NSDictionary 經(jīng)常使用 copy 關鍵字春瞬,為什么?如果改用strong關鍵字套啤,可能造成什么問題宽气?

答:用 @property 聲明 NSString、NSArray潜沦、NSDictionary 經(jīng)常使用 copy 關鍵字萄涯,是因為他們有對應的可變類型:NSMutableString、NSMutableArray唆鸡、NSMutableDictionary涝影,他們之間可能進行賦值操作(就是把可變的賦值給不可變的),為確保對象中的字符串值不會無意間變動争占,應該在設置新屬性值時拷貝一份燃逻。

因為父類指針可以指向子類對象,使用 copy 的目的是為了讓本對象的屬性不受外界影響,使用 copy 無論給我傳入是一個可變對象還是不可對象,我本身持有的就是一個不可變的副本序目。

如果我們使用是 strong ,那么這個屬性就有可能指向一個可變對象,如果這個可變對象在外部被修改了,那么會影響該屬性。

//總結(jié):使用copy的目的是唆樊,防止把可變類型的對象賦值給不可變類型的對象時,可變類型對象的值發(fā)送變化會無意間篡改不可變類型對象原來的值刻蟹。

淺拷貝和深拷貝的區(qū)別逗旁?

答: 淺拷貝:只復制指向?qū)ο蟮闹羔槪粡椭埔脤ο蟊旧怼?深拷貝:復制引用對象本身舆瘪。內(nèi)存中存在了兩份獨立對象本身片效,當修改A時,A_copy不變英古。

系統(tǒng)對象的 copy 與 mutableCopy 方法

不管是集合類對象(NSArray淀衣、NSDictionary、NSSet ... 之類的對象)召调,還是非集合類對象(NSString, NSNumber ... 之類的對象)膨桥,接收到copy和mutableCopy消息時,都遵循以下準則:

copy 返回的是不可變對象(immutableObject)唠叛;如果用copy返回值調(diào)用mutable對象的方法就會crash只嚣。

mutableCopy 返回的是可變對象(mutableObject)。

一艺沼、非集合類對象的copy與mutableCopy 在非集合類對象中册舞,對不可變對象進行copy操作,是指針復制障般,mutableCopy操作是內(nèi)容復制调鲸; 對可變對象進行copy和mutableCopy都是內(nèi)容復制。用代碼簡單表示如下: NSStringstr = @"hello word!"; NSStringstrCopy = [str copy] // 指針復制挽荡,strCopy與str的地址一樣 NSMutableString *strMCopy = [str mutableCopy] // 內(nèi)容復制藐石,strMCopy與str的地址不一樣

NSMutableStringmutableStr = [NSMutableString stringWithString: @"hello word!"]; NSStringstrCopy = [mutableStr copy] // 內(nèi)容復制 NSMutableString *strMCopy = [mutableStr mutableCopy] // 內(nèi)容復制

二、集合類對象的copy與mutableCopy (同上) 在集合類對象中定拟,對不可變對象進行copy操作贯钩,是指針復制,mutableCopy操作是內(nèi)容復制办素; 對可變對象進行copy和mutableCopy都是內(nèi)容復制角雷。但是:集合對象的內(nèi)容復制僅限于對象本身,對集合內(nèi)的對象元素仍然是指針復制性穿。(即單層內(nèi)容復制) NSArrayarr = @[@[@"a", @"b"], @[@"c", @"d"]; NSArraycopyArr = [arr copy]; // 指針復制 NSMutableArray *mCopyArr = [arr mutableCopy]; //單層內(nèi)容復制

NSMutableArray*array = [NSMutableArrayarrayWithObjects:[NSMutableStringstringWithString:@"a"],@"b",@"c",nil];NSArray*copyArr = [mutableArrcopy];// 單層內(nèi)容復制NSMutableArray*mCopyArr = [mutableArr mutableCopy];// 單層內(nèi)容復制

【總結(jié)一句話】: 只有對不可變對象進行copy操作是指針復制(淺復制)勺三,其它情況都是內(nèi)容復制(深復制)!

這個寫法會出什么問題:@property (nonatomic, copy) NSMutableArray *arr;

問題:添加,刪除,修改數(shù)組內(nèi)的元素的時候,程序會因為找不到對應的方法而崩潰需曾。 //如:-[__NSArrayI removeObjectAtIndex:]: unrecognized selector sent to instance 0x7fcd1bc30460 // copy后返回的是不可變對象(即 arr 是 NSArray 類型吗坚,NSArray 類型對象不能調(diào)用 NSMutableArray 類型對象的方法) 原因:是因為 copy 就是復制一個不可變 NSArray 的對象祈远,不能對 NSArray 對象進行添加/修改。

如何讓自己的類用 copy 修飾符商源?如何重寫帶 copy 關鍵字的 setter车份?

若想令自己所寫的對象具有拷貝功能,則需實現(xiàn) NSCopying 協(xié)議牡彻。如果自定義的對象分為可變版本與不可變版本扫沼,那么就要同時實現(xiàn) NSCopying 與 NSMutableCopying 協(xié)議。 具體步驟:

需聲明該類遵從 NSCopying 協(xié)議

實現(xiàn) NSCopying 協(xié)議的方法庄吼。 // 該協(xié)議只有一個方法:

(id)copyWithZone:(NSZone *)zone; // 注意:使用 copy 修飾符缎除,調(diào)用的是copy方法,其實真正需要實現(xiàn)的是 “copyWithZone” 方法总寻。

寫一個 setter 方法用于完成 @property (nonatomic, retain) NSStringname器罐,寫一個 setter 方法用于完成 @property (nonatomic, copy) NSStringname

答: // retain

(void)setName:(NSString *)str { [str retain]; [_name release]; _name = str; } // copy

(void)setName:(NSString *)str { id t = [str copy]; [_name release]; _name = t; }

@synthesize 和 @dynamic 分別有什么作用?

@property有兩個對應的詞渐行,一個是@synthesize(合成實例變量)轰坊,一個是@dynamic。 如果@synthesize和@dynamic都沒有寫祟印,那么默認的就是 @synthesize var = _var; // 在類的實現(xiàn)代碼里通過 @synthesize 語法可以來指定實例變量的名字衰倦。(@synthesize var = _newVar;)

@synthesize 的語義是如果你沒有手動實現(xiàn)setter方法和getter方法,那么編譯器會自動為你加上這兩個方法旁理。

@dynamic 告訴編譯器樊零,屬性的setter與getter方法由用戶自己實現(xiàn),不自動生成(如孽文,@dynamic var)驻襟。

常見的 Objective-C 的數(shù)據(jù)類型有那些,和C的基本數(shù)據(jù)類型有什么區(qū)別芋哭?如:NSInteger和int

答: Objective-C的數(shù)據(jù)類型有NSString沉衣,NSNumber,NSArray减牺,NSMutableArray豌习,NSData等等,這些都是class拔疚,創(chuàng)建后便是對象肥隆,而C語言的基本數(shù)據(jù)類型int,只是一定字節(jié)的內(nèi)存空間稚失,用于存放數(shù)值;NSInteger是基本數(shù)據(jù)類型栋艳,并不是NSNumber的子類,當然也不是NSObject的子類句各。NSInteger是基本數(shù)據(jù)類型Int或者Long的別名(NSInteger的定義typedef long NSInteger)吸占,它的區(qū)別在于晴叨,NSInteger會根據(jù)系統(tǒng)是32位還是64位來決定是本身是int還是long。

id 聲明的對象有什么特性矾屯?

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

Objective-C 如何對內(nèi)存管理的件蚕,說說你的看法和解決方法孙技?

答:Objective-C的內(nèi)存管理主要有三種方式ARC(自動內(nèi)存計數(shù))、手動內(nèi)存計數(shù)骤坐、內(nèi)存池绪杏。 1). 自動內(nèi)存計數(shù)ARC:由Xcode自動在App編譯階段下愈,在代碼中添加內(nèi)存管理代碼纽绍。 2). 手動內(nèi)存計數(shù)MRC:遵循內(nèi)存誰申請虫腋、誰釋放摧玫;誰添加,誰釋放的原則心包。 3). 內(nèi)存釋放池Release Pool:把需要釋放的內(nèi)存統(tǒng)一放在一個池子中履因,當池子被抽干后(drain)障簿,池子中所有的內(nèi)存空間也被自動釋放掉。內(nèi)存池的釋放操作分為自動和手動栅迄。自動釋放受runloop機制影響站故。

Objective-C 中創(chuàng)建線程的方法是什么?如果在主線程中執(zhí)行代碼毅舆,方法是什么西篓?如果想延時執(zhí)行代碼、方法又是什么憋活?

答:線程創(chuàng)建有三種方法:使用NSThread創(chuàng)建岂津、使用GCD的dispatch、使用子類化的NSOperation,然后將其加入NSOperationQueue;在主線程執(zhí)行代碼悦即,方法是performSelectorOnMainThread吮成,如果想延時執(zhí)行代碼可以用performSelector:onThread:withObject:waitUntilDone:

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

區(qū)別:

分類有名字辜梳,類擴展沒有分類名字粱甫,是一種特殊的分類。

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

繼承可以增加节预,修改或者刪除方法叶摄,并且可以增加屬性。

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

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

為什么我們常見的delegate屬性都用是week而不是retain/strong会傲?

答:是為了防止delegate兩端產(chǎn)生不必要的循環(huán)引用。 @property (nonatomic, weak) iddelegate;

什么時候用delete拙泽,什么時候用Notification淌山?

Delegate(委托模式):1對1的反向消息通知功能。 Notification(通知模式):只想要把消息發(fā)送出去顾瞻,告知某些狀態(tài)的變化泼疑。但是并不關心誰想要知道這個。

什么是 KVO 和 KVC荷荤?

1). KVC(Key-Value-Coding):鍵值編碼 是一種通過字符串間接訪問對象的方式(即給屬性賦值) 舉例說明: stu.name = @"張三" // 點語法給屬性賦值 [stu setValue:@"張三" forKey:@"name"]; // 通過字符串使用KVC方式給屬性賦值 stu1.nameLabel.text = @"張三"; [stu1 setValue:@"張三" forKey:@"nameLabel.text"]; // 跨層賦值 2). KVO(key-Value-Observing):鍵值觀察機制 他提供了觀察某一屬性變化的方法退渗,極大的簡化了代碼。 KVO只能被KVC觸發(fā)蕴纳,包括使用setValue:forKey:方法和點語法会油。 // 通過下方方法為屬性添加KVO觀察

(void)addObserver:(NSObject)observer forKeyPath:(NSString)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context; // 當被觀察的屬性發(fā)送變化時,會自動觸發(fā)下方方法

(void)observeValueForKeyPath:(NSString)keyPath ofObject:(id)object change:(NSDictionary)change context:(void *)context{}

KVC 和 KVO 的 keyPath 可以是屬性古毛、實例變量翻翩、成員變量。

KVC的底層實現(xiàn)稻薇?

當一個對象調(diào)用setValue方法時嫂冻,方法內(nèi)部會做以下操作: 1). 檢查是否存在相應的key的set方法,如果存在颖低,就調(diào)用set方法絮吵。 2). 如果set方法不存在,就會查找與key相同名稱并且?guī)聞澗€的成員變量忱屑,如果有蹬敲,則直接給成員變量屬性賦值。 3). 如果沒有找到_key莺戒,就會查找相同名稱的屬性key伴嗡,如果有就直接賦值。 4). 如果還沒有找到从铲,則調(diào)用valueForUndefinedKey:和setValue:forUndefinedKey:方法瘪校。 這些方法的默認實現(xiàn)都是拋出異常,我們可以根據(jù)需要重寫它們。

KVO的底層實現(xiàn)阱扬?

KVO基于runtime機制實現(xiàn)泣懊。

ViewController生命周期

按照執(zhí)行順序排列:

initWithCoder:通過nib文件初始化時觸發(fā)。

awakeFromNib:nib文件被加載的時候麻惶,會發(fā)生一個awakeFromNib的消息到nib文件中的每個對象馍刮。

loadView:開始加載視圖控制器自帶的view。

viewDidLoad:視圖控制器的view被加載完成窃蹋。

viewWillAppear:視圖控制器的view將要顯示在window上卡啰。

updateViewConstraints:視圖控制器的view開始更新AutoLayout約束。

viewWillLayoutSubviews:視圖控制器的view將要更新內(nèi)容視圖的位置警没。

viewDidLayoutSubviews:視圖控制器的view已經(jīng)更新視圖的位置匈辱。

viewDidAppear:視圖控制器的view已經(jīng)展示到window上。

viewWillDisappear:視圖控制器的view將要從window上消失杀迹。

viewDidDisappear:視圖控制器的view已經(jīng)從window上消失亡脸。

方法和選擇器有何不同?

selector是一個方法的名字佛南,方法是一個組合體梗掰,包含了名字和實現(xiàn)嵌言。

你是否接觸過OC中的反射機制嗅回?簡單聊一下概念和使用

1). class反射 通過類名的字符串形式實例化對象。 Class class = NSClassFromString(@"student"); Studentstu = [[class alloc] init]; 將類名變?yōu)樽址?Class class =[Student class]; NSStringclassName = NSStringFromClass(class); 2). SEL的反射 通過方法的字符串形式實例化方法摧茴。 SEL selector = NSSelectorFromString(@"setName");

[stu performSelector:selector withObject:@"Mike"]; 將方法變成字符串绵载。 NSStringFromSelector(@selector*(setName:));

調(diào)用方法有兩種方式:

1). 直接通過方法名來調(diào)用。[person show]; 2). 間接的通過SEL數(shù)據(jù)來調(diào)用 SEL aaa = @selector(show); [person performSelector:aaa];

如何對iOS設備進行性能測試苛白?

答: Profile-> Instruments ->Time Profiler

開發(fā)項目時你是怎么檢查內(nèi)存泄露娃豹?

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

什么是懶加載懂版?

答:懶加載就是只在用到的時候才去初始化。也可以理解成延時加載躏率。 我覺得最好也最簡單的一個例子就是tableView中圖片的加載顯示了, 一個延時加載, 避免內(nèi)存過高,一個異步加載,避免線程堵塞提高用戶體驗躯畴。

類變量的 @public,@protected薇芝,@private蓬抄,@package 聲明各有什么含義?

@public 任何地方都能訪問; @protected 該類和子類中訪問,是默認的; @private 只能在本類中訪問; @package 本包內(nèi)使用,跨包不可以夯到。

什么是謂詞嚷缭?

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

isa指針問題

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

如何訪問并修改一個類的私有屬性?

1). 一種是通過KVC獲取胆敞。 2). 通過runtime訪問并修改私有屬性着帽。

一個objc對象的isa的指針指向什么?有什么作用移层?

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

下面的代碼輸出什么?

@implementation Son : Father

(id)init { if (self = [super init]) { NSLog(@"%@", NSStringFromClass([self class])); // Son NSLog(@"%@", NSStringFromClass([super class])); // Son } return self; } @end // 解析: self 是類的隱藏參數(shù)观话,指向當前調(diào)用方法的這個類的實例予借。 super是一個Magic Keyword,它本質(zhì)是一個編譯器標示符频蛔,和self是指向的同一個消息接收者灵迫。 不同的是:super會告訴編譯器,調(diào)用class這個方法時晦溪,要去父類的方法瀑粥,而不是本類里的。 上面的例子不管調(diào)用[self class]還是[super class]三圆,接受消息的對象都是當前 Son *obj 這個對象狞换。

寫一個完整的代理,包括聲明舟肉、實現(xiàn)

// 創(chuàng)建 @protocol MyDelagate @required -(void)eat:(NSString *)foodName; @optional -(void)run; @end

// 聲明 .h @interface person: NSObject

@end

// 實現(xiàn) .m @implementation person

(void)eat:(NSString *)foodName { NSLog(@"吃:%@!", foodName); }

(void)run { NSLog(@"run!"); }

@end

isKindOfClass修噪、isMemberOfClass、selector作用分別是什么

isKindOfClass:作用是某個對象屬于某個類型或者繼承自某類型路媚。 isMemberOfClass:某個對象確切屬于某個類型黄琼。 selector:通過方法名,獲取在內(nèi)存中的函數(shù)的入口地址整慎。

delegate 和 notification 的區(qū)別

1). 二者都用于傳遞消息脏款,不同之處主要在于一個是一對一的,另一個是一對多的院领。 2). notification通過維護一個array弛矛,實現(xiàn)一對多消息的轉(zhuǎn)發(fā)。 3). delegate需要兩者之間必須建立聯(lián)系比然,不然沒法調(diào)用代理的方法丈氓;notification不需要兩者之間有聯(lián)系。

什么是block?

閉包(block):閉包就是獲取其它函數(shù)局部變量的匿名函數(shù)万俗。

block反向傳值

在控制器間傳值可以使用代理或者block湾笛,使用block相對來說簡潔。

在前一個控制器的touchesBegan:方法內(nèi)實現(xiàn)如下代碼闰歪。

// OneViewController.m TwoViewControllertwoVC = [[TwoViewController alloc] init]; twoVC.valueBlcok = ^(NSStringstr) { NSLog(@"OneViewController拿到值:%@", str); }; [self presentViewController:twoVC animated:YES completion:nil];

// TwoViewController.h (在.h文件中聲明一個block屬性) @property (nonatomic ,strong) void(^valueBlcok)(NSString *str);

// TwoViewController.m (在.m文件中實現(xiàn)方法)

(void)touchesBegan:(NSSet)touches withEvent:(UIEvent)event { // 傳值:調(diào)用block if (_valueBlcok) { _valueBlcok(@"123456"); } }

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修飾外部變量教翩。

BAD_ACCESS在什么情況下出現(xiàn)杆勇?

答:這種問題在開發(fā)時經(jīng)常遇到。原因是訪問了野指針饱亿,比如訪問已經(jīng)釋放對象的成員變量或者發(fā)消息蚜退、死循環(huán)等。

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的簡寫

你一般是怎么用Instruments的窒舟?

Instruments里面工具很多系忙,常用: 1). Time Profiler: 性能分析 2). Zombies:檢查是否訪問了僵尸對象,但是這個工具只能從上往下檢查惠豺,不智能银还。 3). Allocations:用來檢查內(nèi)存,寫算法的那批人也用這個來檢查洁墙。 4). Leaks:檢查內(nèi)存蛹疯,看是否有內(nèi)存泄露。

iOS中常用的數(shù)據(jù)存儲方式有哪些热监?

數(shù)據(jù)存儲有四種方案:NSUserDefault捺弦、KeyChain、file、DB列吼。 其中File有三種方式:plist幽崩、Archive(歸檔) DB包括:SQLite、FMDB寞钥、CoreData

iOS的沙盒目錄結(jié)構(gòu)是怎樣的慌申?

沙盒結(jié)構(gòu): 1). Application:存放程序源文件,上架前經(jīng)過數(shù)字簽名理郑,上架后不可修改蹄溉。 2). Documents:常用目錄,iCloud備份目錄您炉,存放數(shù)據(jù)类缤。(這里不能存緩存文件,否則上架不被通過) 3). Library: Caches:存放體積大又不需要備份的數(shù)據(jù)邻吭。(常用的緩存路徑) Preference:設置目錄餐弱,iCloud會備份設置信息。 4). tmp:存放臨時文件囱晴,不會被備份膏蚓,而且這個文件下的數(shù)據(jù)有可能隨時被清除的可能。

iOS多線程技術(shù)有哪幾種方式畸写?

答:pthread驮瞧、NSThread、GCD枯芬、NSOperation

GCD 與 NSOperation 的區(qū)別:

GCD 和 NSOperation 都是用于實現(xiàn)多線程: GCD 基于C語言的底層API论笔,GCD主要與block結(jié)合使用,代碼簡潔高效千所。 NSOperation 屬于Objective-C類狂魔,是基于GCD更高一層的封裝。復雜任務一般用NSOperation實現(xiàn)淫痰。

寫出使用GCD方式從子線程回到主線程的方法代碼

答:dispatch_sync(dispatch_get_main_queue(), ^{ });

如何用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/ }); // 當并發(fā)隊列組中的任務執(zhí)行完畢后才會執(zhí)行這里的代碼 dispatch_group_notify(group, dispatch_get_main_queue(), ^{ // 合并圖片 });

dispatch_barrier_async(柵欄函數(shù))的作用是什么?

函數(shù)定義:dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block); 作用: 1.在它前面的任務執(zhí)行結(jié)束后它才執(zhí)行火俄,它后面的任務要等它執(zhí)行完成后才會開始執(zhí)行犯建。 2.避免數(shù)據(jù)競爭

// 1.創(chuàng)建并發(fā)隊列 dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT); // 2.向隊列中添加任務 dispatch_async(queue, ^{ // 1.2是并行的 NSLog(@"任務1, %@",[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"任務2, %@",[NSThread currentThread]); });

dispatch_barrier_async(queue, ^{ NSLog(@"任務 barrier, %@", [NSThread currentThread]); });

dispatch_async(queue, ^{ // 這兩個是同時執(zhí)行的 NSLog(@"任務3, %@",[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"任務4, %@",[NSThread currentThread]); });

// 輸出結(jié)果: 任務1 任務2 ——》 任務 barrier ——》任務3 任務4 // 其中的任務1與任務2,任務3與任務4 由于是并行處理先后順序不定瓜客。

以下代碼運行結(jié)果如何适瓦?

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

什么是 RunLoop

從字面上講就是運行循環(huán),它內(nèi)部就是do-while循環(huán)犹菇,在這個循環(huán)內(nèi)部不斷地處理各種任務德迹。 一個線程對應一個RunLoop,基本作用就是保持程序的持續(xù)運行揭芍,處理app中的各種事件胳搞。通過runloop,有事運行称杨,沒事就休息肌毅,可以節(jié)省cpu資源,提高程序性能姑原。

主線程的run loop默認是啟動的悬而。iOS的應用程序里面,程序啟動后會有一個如下的main()函數(shù) int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } }

什么是 Runtime

Runtime又叫運行時锭汛,是一套底層的C語言API笨奠,其為iOS內(nèi)部的核心之一,我們平時編寫的OC代碼唤殴,底層都是基于它來實現(xiàn)的般婆。

Runtime實現(xiàn)的機制是什么,怎么用朵逝,一般用于干嘛蔚袍?

1). 使用時需要導入的頭文件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庫里面包含了跟類器仗、成員變量融涣、方法相關的API童番。 比如: (1)獲取類里面的所有成員變量。 (2)為類動態(tài)添加成員變量威鹿。 (3)動態(tài)改變類的方法實現(xiàn)剃斧。 (4)為類動態(tài)添加新的方法等。 因此忽你,有了Runtime幼东,想怎么改就怎么改。

什么是 Method Swizzle(黑魔法)科雳,什么情況下會使用根蟹?

1). 在沒有一個類的實現(xiàn)源碼的情況下,想改變其中一個方法的實現(xiàn)糟秘,除了繼承它重寫简逮、和借助類別重名方法暴力搶先之外,還有更加靈活的方法 Method Swizzle尿赚。 2). Method Swizzle 指的是改變一個已存在的選擇器對應的實現(xiàn)的過程散庶。OC中方法的調(diào)用能夠在運行時通過改變,通過改變類的調(diào)度表中選擇器到最終函數(shù)間的映射關系凌净。 3). 在OC中調(diào)用一個方法督赤,其實是向一個對象發(fā)送消息,查找消息的唯一依據(jù)是selector的名字泻蚊。利用OC的動態(tài)特性躲舌,可以實現(xiàn)在運行時偷換selector對應的方法實現(xiàn)。 4). 每個類都有一個方法列表性雄,存放著selector的名字和方法實現(xiàn)的映射關系没卸。IMP有點類似函數(shù)指針,指向具體的方法實現(xiàn)秒旋。 5). 我們可以利用 method_exchangeImplementations 來交換2個方法中的IMP约计。 6). 我們可以利用 class_replaceMethod 來修改類。 7). 我們可以利用 method_setImplementation 來直接設置某個方法的IMP迁筛。 8). 歸根結(jié)底煤蚌,都是偷換了selector的IMP。

_objc_msgForward 函數(shù)是做什么的细卧,直接調(diào)用它將會發(fā)生什么尉桩?

答:_objc_msgForward是 IMP 類型,用于消息轉(zhuǎn)發(fā)的:當向一個對象發(fā)送一條消息贪庙,但它并沒有實現(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ù)傳輸快點巍实,但安全性一般。

通信底層原理(OSI七層模型)

OSI采用了分層的結(jié)構(gòu)化技術(shù)哩牍,共分七層: 物理層棚潦、數(shù)據(jù)鏈路層、網(wǎng)絡層膝昆、傳輸層丸边、會話層、表示層荚孵、應用層妹窖。

介紹一下XMPP?

XMPP是一種以XML為基礎的開放式實時通信協(xié)議收叶。 簡單的說骄呼,XMPP就是一種協(xié)議,一種規(guī)定判没。就是說蜓萄,在網(wǎng)絡上傳東西,XMM就是規(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的重用機制绸硕?

答:UITableView 通過重用單元格來達到節(jié)省內(nèi)存的目的: 通過為每個單元格指定一個重用標識符,即指定了單元格的種類,當屏幕上的單元格滑出屏幕時魂毁,系統(tǒng)會把這個單元格添加到重用隊列中玻佩,等待被重用,當有新單元格從屏幕外滑入屏幕內(nèi)時漱牵,從重用隊列中找看有沒有可以重用的單元格夺蛇,如果有,就拿過來用酣胀,如果沒有就創(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; }

如何實現(xiàn)視圖的變形?

答:通過修改view的 transform 屬性即可。

在手勢對象基礎類UIGestureRecognizer的常用子類手勢類型中哪兩個手勢發(fā)生后闻镶,響應只會執(zhí)行一次甚脉?

答:UITapGestureRecognizer,UISwipeGestureRecognizer是一次性手勢,手勢發(fā)生后,響應只會執(zhí)行一次。

字符串常用方法:

NSStringstr = @"abc123"; NSArrayarr = [str componentsSeparatedByString:@""]; //以目標字符串把原字符串分割成兩部分铆农,存到數(shù)組中牺氨。@[@"abc", @"123"];

如何高性能的給 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]; UIImageimage = UIGraphicsGetImageFromCurrentImageContext(); // 關閉上下文 UIGraphicsEndImageContext(); return image; }

還有一種方案:使用了貝塞爾曲線"切割"個這個圖片, 給UIImageView 添加了的圓角猴凹,其實也是通過繪圖技術(shù)來實現(xiàn)的。

UIImageViewimageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]; imageView.center = CGPointMake(200, 300); UIImageanotherImage = [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相關的模型岭皂,然后將模型數(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ū)別?

GET用于向服務器請求數(shù)據(jù),POST用于提交數(shù)據(jù)

GET請求爷绘,請求參數(shù)拼接形式暴露在地址欄书劝,而POST請求參數(shù)則放在請求體里面,因此GET請求不適合用于驗證密碼等操作

GET請求的URL有長度限制土至,POST請求不會有長度限制

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

APNS優(yōu)勢:杜絕了類似安卓那種為了接受通知不停在后臺喚醒程序保持長連接的行為购对,由iOS系統(tǒng)和APNS進行長連接替代。 APNS的原理: 1). 應用在通知中心注冊陶因,由iOS系統(tǒng)向APNS請求返回設備令牌(device Token) 2). 應用程序接收到設備令牌并發(fā)送給自己的后臺服務器 3). 服務器把要推送的內(nèi)容和設備發(fā)送給APNS 4). APNS根據(jù)設備令牌找到設備骡苞,再由iOS根據(jù)APPID把推送內(nèi)容展示

?

第三方框架 AFNetworking 底層原理分析

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

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

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

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

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

SDWebImage原理: 調(diào)用類別的方法:

從內(nèi)存(字典)中找圖片(當這個圖片在本次使用程序的過程中已經(jīng)被加載過),找到直接使用助被。

從沙盒中找(當這個圖片在之前使用程序的過程中被加載過)剖张,找到使用切诀,緩存到內(nèi)存中。

從網(wǎng)絡上獲取搔弄,使用幅虑,緩存到內(nèi)存,緩存到沙盒顾犹。

友盟統(tǒng)計接口統(tǒng)計的所有功能

APP啟動速度倒庵,APP停留頁面時間等

算法 不用中間變量,用兩種方法交換A和B的值

// 1.中間變量 void swap(int a, int b) { int temp = a; a = b; b = temp; }

// 2.加法 void swap(int a, int b) { a = a + b; b = a - b; a = a - b; }

// 3.異或(相同為0,不同為1. 可以理解為不進位加法) void swap(int a, int b) { a = a ^ b; b = a ^ b; a = a ^ b; }

?

求最大公約數(shù)

/*1.直接遍歷法/ int maxCommonDivisor(int a, int b) { int max = 0; for (int i = 1; i <=b; i++) { if (a % i == 0 && b % i == 0) { max = i; } } return max; } /*2.輾轉(zhuǎn)相除法/ int maxCommonDivisor(int a, int b) { int r; while(a % b > 0) { r = a % b; a = b; b = r; } return b; }

// 擴展:最小公倍數(shù) = (a * b)/最大公約數(shù)

模擬棧操作

/**

棧是一種數(shù)據(jù)結(jié)構(gòu)炫刷,特點:先進后出

練習:使用全局變量模擬棧的操作 */

include

include

include

//保護全局變量:在全局變量前加static后擎宝,這個全局變量就只能在本文件中使用 static int data[1024];//棧最多能保存1024個數(shù)據(jù) static int count = 0;//目前已經(jīng)放了多少個數(shù)(相當于棧頂位置)

//數(shù)據(jù)入棧 push void push(int x){ assert(!full());//防止數(shù)組越界 data[count++] = x; } //數(shù)據(jù)出棧 pop int pop(){ assert(!empty()); return data[--count]; } //查看棧頂元素 top int top(){ assert(!empty()); return data[count-1]; }

//查詢棧滿 full bool full() { if(count >= 1024) { return 1; } return 0; }

//查詢棧空 empty bool empty() { if(count <= 0) { return 1; } return 0; }

int main(){ //入棧 for (int i = 1; i <= 10; i++) { push(i); }

//出棧while(!empty()){printf("%d ", top());//棧頂元素pop();//出棧}printf("\n");return0;

}

排序算法

選擇排序浑玛、冒泡排序绍申、插入排序三種排序算法可以總結(jié)為如下:

都將數(shù)組分為已排序部分和未排序部分。

選擇排序?qū)⒁雅判虿糠侄x在左端锄奢,然后選擇未排序部分的最小元素和未排序部分的第一個元素交換失晴。

冒泡排序?qū)⒁雅判虿糠侄x在右端,在遍歷未排序部分的過程執(zhí)行交換拘央,將最大元素交換到最右端涂屁。

插入排序?qū)⒁雅判虿糠侄x在左端,將未排序部分元的第一個元素插入到已排序部分合適的位置灰伟。

選擇排序

/**

【選擇排序】:最值出現(xiàn)在起始端

第1趟:在n個數(shù)中找到最小(大)數(shù)與第一個數(shù)交換位置

第2趟:在剩下n-1個數(shù)中找到最小(大)數(shù)與第二個數(shù)交換位置

重復這樣的操作...依次與第三個拆又、第四個...數(shù)交換位置

第n-1趟,最終可實現(xiàn)數(shù)據(jù)的升序(降序)排列栏账。

/ void selectSort(intarr, int length) { for (int i = 0; i < length xss=removed> arr[j]) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } } }

冒泡排序

/**

【冒泡排序】:相鄰元素兩兩比較帖族,比較完一趟,最值出現(xiàn)在末尾

第1趟:依次比較相鄰的兩個數(shù)挡爵,不斷交換(小數(shù)放前竖般,大數(shù)放后)逐個推進,最值最后出現(xiàn)在第n個元素位置

第2趟:依次比較相鄰的兩個數(shù)茶鹃,不斷交換(小數(shù)放前涣雕,大數(shù)放后)逐個推進,最值最后出現(xiàn)在第n-1個元素位置

…… ……

第n-1趟:依次比較相鄰的兩個數(shù)闭翩,不斷交換(小數(shù)放前挣郭,大數(shù)放后)逐個推進,最值最后出現(xiàn)在第2個元素位置/ void bublleSort(intarr, int length) { for(int i = 0; i < length xss=removed> arr[j+1]) { int temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } } }

折半查找(二分查找)

/**

折半查找:優(yōu)化查找時間(不用遍歷全部數(shù)據(jù))

折半查找的原理:

1> 數(shù)組必須是有序的

2> 必須已知min和max(知道范圍)

3> 動態(tài)計算mid的值疗韵,取出mid對應的值進行比較

4> 如果mid對應的值大于要查找的值兑障,那么max要變小為mid-1

5> 如果mid對應的值小于要查找的值资厉,那么min要變大為mid+1

*/

// 已知一個有序數(shù)組, 和一個key, 要求從數(shù)組中找到key對應的索引位置 int findKey(int *arr, int length, int key) { int min = 0, max = length - 1, mid; while (min <= max) { mid = (min + max) / 2; //計算中間值 if (key > arr[mid]) { min = mid + 1; } else if (key < arr xss=removed>

@property (nonatomic, readonly, copy) NSString *name; @property (nonatomic, readonly, assign) NSUInteger age; @property (nonatomic, readonly, assign) BRUserGender gender;

(instancetype)initWithName:(NSString *)name age:(NSUInteger)age gender:(BRUserGender)gender;

@end

//說明: //既然該類中已經(jīng)有一個“初始化方法” 问芬,用于設置 name嫁乘、age 和 gender 的初始值: 那么在設計對應 @property 時就應該盡量使用不可變的對象:其三個屬性都應該設為“只讀”疆柔。用初始化方法設置好屬性值之后活翩,就不能再改變了刁俭。 //屬性的參數(shù)應該按照下面的順序排列: (原子性职恳,讀寫辩撑,內(nèi)存管理)

?

避免使用C語言中的基本數(shù)據(jù)類型宛渐,建議使用 Foundation 數(shù)據(jù)類型竞漾,對應關系如下:

int -> NSInteger unsigned -> NSUInteger float -> CGFloat 動畫時間 -> NSTimeInterval

?

其它知識點 HomeKit,是蘋果2014年發(fā)布的智能家居平臺窥翩。

什么是 OpenGL业岁、Quartz 2D?

Quatarz 2d 是Apple提供的基本圖形工具庫寇蚊。只是適用于2D圖形的繪制笔时。 OpenGL,是一個跨平臺的圖形開發(fā)庫仗岸。適用于2D和3D圖形的繪制允耿。

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

談談 UITableView 的優(yōu)化

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

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

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

說說你對 block 的理解

棧上的自動復制到堆上扔枫,block 的屬性修飾符是 copy汛聚,循環(huán)引用的原理和解決方案。

說說你對 runtime 的理解

主要是方法調(diào)用時如何查找緩存短荐,如何找到方法倚舀,找不到方法時怎么轉(zhuǎn)發(fā),對象的內(nèi)存布局忍宋。

什么是野指針痕貌、空指針?

野指針:不知道指向了哪里的指針叫野指針糠排。即指針指向不確定舵稠,指針存的地址是一個垃圾值,未初始化入宦。 空指針:不指向任何位置的指針叫空指針哺徊。即指針沒有指向,指針存的地址是一個空地址乾闰,NULL落追。

什么是 OOA / OOD / OOP ?

OOA(Object Oriented Analysis) --面向?qū)ο蠓治?OOD(Object Oriented Design) --面向?qū)ο笤O計 OOP(Object Oriented Programming)--面向?qū)ο缶幊?/p>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市汹忠,隨后出現(xiàn)的幾起案子淋硝,更是在濱河造成了極大的恐慌,老刑警劉巖宽菜,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谣膳,死亡現(xiàn)場離奇詭異,居然都是意外死亡铅乡,警方通過查閱死者的電腦和手機继谚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來阵幸,“玉大人花履,你說我怎么就攤上這事≈可蓿” “怎么了诡壁?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長荠割。 經(jīng)常有香客問我妹卿,道長旺矾,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任夺克,我火速辦了婚禮箕宙,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘铺纽。我一直安慰自己柬帕,他們只是感情好,可當我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布狡门。 她就那樣靜靜地躺著陷寝,像睡著了一般。 火紅的嫁衣襯著肌膚如雪融撞。 梳的紋絲不亂的頭發(fā)上盼铁,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天,我揣著相機與錄音尝偎,去河邊找鬼。 笑死鹏控,一個胖子當著我的面吹牛致扯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播当辐,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼抖僵,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了缘揪?” 一聲冷哼從身側(cè)響起耍群,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎找筝,沒想到半個月后蹈垢,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡袖裕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年曹抬,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片急鳄。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡谤民,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出疾宏,到底是詐尸還是另有隱情张足,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布坎藐,位于F島的核電站为牍,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜吵聪,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一凌那、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧吟逝,春花似錦帽蝶、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至囱井,卻和暖如春驹尼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背庞呕。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工新翎, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人住练。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓地啰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親讲逛。 傳聞我的和親對象是個殘疾皇子亏吝,可洞房花燭夜當晚...
    茶點故事閱讀 45,435評論 2 359

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

  • 設計模式是什么? 你知道哪些設計模式盏混,并簡要敘述蔚鸥? 設計模式是一種編碼經(jīng)驗,就是用比較成熟的邏輯去處理某一種類型的...
    如果我們是朋友閱讀 675評論 0 9
  • 設計模式是什么许赃? 你知道哪些設計模式止喷,并簡要敘述? 設計模式是一種編碼經(jīng)驗图焰,就是用比較成熟的邏輯去處理某一種類型的...
    small_Sun閱讀 454評論 0 4
  • 設計模式是什么启盛? 你知道哪些設計模式,并簡要敘述技羔?設計模式是一種編碼經(jīng)驗僵闯,就是用比較成熟的邏輯去處理某一種類型的事...
    irenb閱讀 5,215評論 1 21
  • iOS面試小貼士 ———————————————回答好下面的足夠了------------------------...
    不言不愛閱讀 1,988評論 0 7
  • 多線程、特別是NSOperation 和 GCD 的內(nèi)部原理藤滥。運行時機制的原理和運用場景鳖粟。SDWebImage的原...
    LZM輪回閱讀 2,009評論 0 12