前言:
最近公司項目不怎么忙, 閑暇時間把iOS 在面試中可能會遇到的問題整理了一番, 一部分題目是自己面試遇到的,一部分題目則是網(wǎng)上收錄的, 方便自己鞏固復(fù)習(xí), 也分享給大家! 知識點比較多,比較雜,這里做了分類,下面是分類鏈接地址;
面試知識點整理 - 目錄:
iOS | 面試知識整理 - OC基礎(chǔ) (一)
iOS | 面試知識整理 - OC基礎(chǔ) (二)
iOS | 面試知識整理 - OC基礎(chǔ) (三)
iOS | 面試知識整理 - UI 相 關(guān) (四)
iOS | 面試知識整理 - 內(nèi)存管理 (五)
iOS | 面試知識整理 - 多 線 程 (六)
iOS | 面試知識整理 - 網(wǎng)絡(luò)相關(guān) (七)
iOS | 面試知識整理 - 數(shù)據(jù)持久化 (八)
iOS | 面試知識整理 - Swift 基礎(chǔ) (九)
iOS | 面試知識整理 - OC基礎(chǔ) (一)
1. #include、#import、@class的區(qū)別?
- 在C 語言中, 我們使用
#include
來引入頭文件,如果需要防止重復(fù)導(dǎo)入需要使用#ifndef...#define...#endif
- 在OC語言中, 我們使用
#import
來引入頭文件,可以防止重復(fù)引入頭文件,可以避免出現(xiàn)頭文件遞歸引入的現(xiàn)象。 -
@class
僅用來告訴編譯器,有這樣一個類,編譯代碼時,不報錯,不會拷貝頭文件.如果需要使用該類或者內(nèi)部方法需要使用#import
導(dǎo)入
2. id 和 instancetype的區(qū)別?
-
id
可以作為方法的返回以及參數(shù)類型 也可以用來定義變量 -
instancetype
只能作為函數(shù)或者方法的返回值 - instancetype對比id的好處就是: 能精確的限制返回值的具體類型
3. New 作用是什么?
- 向計算機(堆區(qū))申請內(nèi)存空間;
- 給實例變量初始化;
- 返回所申請空間的首地址;
4.OC實例變量的修飾符? 及作用范圍?
@puplic
1.可以在其他類中訪問被@public修飾的成員變量
2.也可以在本類中訪問被@public修飾的成員變量
3.可以在子類中訪問父類中被@public修飾的成員變量
@private
1.不可可以在其他類中訪問被@private修飾的成員變量
2.也可以在本類中訪問被@private修飾的成員變量
3.不可以在子類中訪問父類中被@private修飾的成員變量
@protected (默認(rèn)情況下所有的實例變量都是protected)
1.不可可以在其他類中訪問被@protected修飾的成員變量
2.也可以在本類中訪問被@protected修飾的成員變量
3.可以在子類中訪問父類中被@protected修飾的成員變量
@package
介于public和private之間的,如果是在其他包中訪問就是private,在當(dāng)前代碼中訪問就是public.
5. @proprety的作用
@property = ivar + getter + setter;
- 在.h文件中幫我們自動生成
get
和set
方法聲明 - 在.m文件中幫我們生成私有的實例變量(前提是沒有在.h文件中沒有手動生成)
- 在.m文件中幫我們是實現(xiàn)
get和set
方法的實現(xiàn)
- 注意:
在使用@property情況下,可以重寫getter和setter方法.需要注意的是, 當(dāng)把setter和getter方法都實現(xiàn)了之后,實例變量也需要手動添加.
6. @proprety 參數(shù)說明?
- 原子性---
atomic/nonatomic
如果不寫默認(rèn)情況為atomic
(系統(tǒng)會自動加上同步鎖,影響性能),在 iOS 開發(fā)中盡量指定為nonatomic
,這樣有助于提高程序的性能 - 讀/寫權(quán)限---
readwrite(讀寫)、readooly (只讀)
- 內(nèi)存管理語義---
retain、assign、strong、 weak、unsafe_unretained、copy
- 方法名---
getter=、setter=
7 NSObject和id的區(qū)別?
- NSObject和id都可以指向任何對象
- NSObject對象會在編譯時進行檢查,需要強制類型轉(zhuǎn)換
- id類型不需要編譯時檢查,不需要強制類型轉(zhuǎn)換
8. id類型, nil , Nil ,NULL和NSNULL的區(qū)別?
- id類型: 是一個獨特的數(shù)據(jù)類型,可以轉(zhuǎn)換為任何數(shù)據(jù)類型,id類型的變量可以存放任何數(shù)據(jù)類型的對象,在內(nèi)部處理上,這種類型被定義為指向?qū)ο蟮闹羔槪瑢嶋H上是一個指向這種對象的實例變量的指針; id 聲明的對象具有運行時特性,既可以指向任意類型的對象
- nil 是一個實例對象值;如果我們要把一個對象設(shè)置為空的時候,就用nil
- Nil 是一個類對象的值,如果我們要把一個class的對象設(shè)置為空的時候,就用Nil
- NULL 指向基本數(shù)據(jù)類型的空指針(C語言的變量的指針為空)
- NSNull 是一個對象,它用在不能使用nil的場合
9. atomic和nonatomic區(qū)別,以及作用?
atomic
與nonatom
的主要區(qū)別就是系統(tǒng)自動生成的getter/setter
方法不一樣
- atomic系統(tǒng)自動生成的getter/setter方法會進行加鎖操作
- nonatomic系統(tǒng)自動生成的getter/setter方法不會進行加鎖操作
atomic不是線程安全的
- 系統(tǒng)生成的getter/setter方法會進行加鎖操作,注意:這個鎖僅僅保證了getter和setter存取方法的線程安全.
- 因為getter/setter方法有加鎖的緣故,故在別的線程來讀寫這個屬性之前,會先執(zhí)行完當(dāng)前操作.
- atomic 可以保證多線程訪問時候,對象是未被其他線程銷毀的(比如:如果當(dāng)一個線程正在get或set時,又有另一個線程同時在進行release操作,可能會直接crash)
10. 什么情況使用 weak 關(guān)鍵字,相比 assign 有 什么不同?
- 在 ARC 中,在有可能出現(xiàn)循環(huán)引用的時候,往往要通過讓其中一端使用
weak
來解決, 比如:delegate
代理屬性, 自身已經(jīng)對它進行一次強引用,沒有必要再強引用一次,此時也會使用weak
,自定義IBOutlet
控件屬性一般也使用weak
;當(dāng)然,也可以使用strong
,但是建議使用weak
weak 和 assign 的不同點
-
weak
策略在屬性所指的對象遭到摧毀時,系統(tǒng)會將weak
修飾的屬性對象的指針指 向nil
,在OC
給nil
發(fā)消息是不會有什么問題的; 如果使用assign
策略在屬性所指 的對象遭到摧毀時,屬性對象指針還指向原來的對象,由于對象已經(jīng)被銷毀,這時候就產(chǎn)生了野指針,如果這時候在給此對象發(fā)送消息,很容造成程序奔潰assigin
可以用于修飾非OC
對象,而weak
必須用于OC
對象
11. 代理使用 weak 還是 assign
- 建議使用
weak
, 對于weak: 指明該對象并不負(fù)責(zé)保持delegate這個對象,delegate這個對象的銷毀由外部控制。 - 可以使用
assign
,也有weak的功效, 對于使用 assign 修飾delegate, 在對象釋放前,需要將 delegate 指針設(shè)置為 nil,不然會產(chǎn)生野指針
12. ARC 下,不顯式指定任何屬性關(guān)鍵字時,默認(rèn) 的關(guān)鍵字都有哪些?
- 基本數(shù)據(jù)類型:
atomic,readwrite,assign
- 普通的 OC 對象:
atomic,readwrite,strong
13. 怎么用 copy 關(guān)鍵字?
-
NSString、NSArray、NSDictionary 等等經(jīng)常使用 copy
關(guān)鍵字,是因為他們有對應(yīng) 的可變類型:NSMutableString、NSMutableArray、NSMutableDictionary
,為確保 對象中的屬性值不會無意間變動,應(yīng)該在設(shè)置新屬性值時拷貝一份,保護其封裝性 -
block
也經(jīng)常使用copy
關(guān)鍵字,方法內(nèi)部的block
默認(rèn)是 在棧區(qū)的,使用copy
可以把它放到堆區(qū). - 對于
block
使用copy
還是strong
效果是一樣的,但是 建議寫上copy
,因為這樣顯示告知調(diào)用者“編譯器會自動對block
進行了copy
操 作
14. 如何讓自定義類可以用 copy 修飾符?如何重寫帶 copy 關(guān)鍵字的 setter?
若想令自己所寫的對象具有拷貝功能,則需實現(xiàn) NSCopying
協(xié)議。如果自定義的對象分為可變版本與不可變版本,那么就要同時實現(xiàn) NSCopyiog 與 NSMutableCopying 協(xié)議
// 實現(xiàn)不可變版本拷貝
- (id)copyWithZone:(NSZone *)zone;
// 實現(xiàn)可變版本拷貝
- (id)mutableCopyWithZone:(NSZone *)zone;
// 重寫帶 copy 關(guān)鍵字的 setter
- (void)setName:(NSString *)name {
_name = [name copy];
}
15. weak 屬性需要在 dealloc 中置 nil 么
- 在 ARC 環(huán)境無論是強指針還是弱指針都無需在 dealloc 設(shè)置為 nil , ARC 會自動幫我們處理
- 即便是編譯器不幫我們做這些,weak 也不需要在 dealloc 中置 nil 在屬性所指的對象遭到摧毀時,屬性值也會清空
16.說一下OC的反射機制;
- OC的反射機制主要是基于OC的動態(tài)語言特性;
- 系統(tǒng)Foundation框架為我們提供了一些方法反射的API;
- 我們可以通過這些API執(zhí)行將字符串轉(zhuǎn)為SEL等操作;
- 由于OC語言的動態(tài)性,這些操作都是發(fā)生在運行時的。
17.手寫單例
方式一: 不是線程安全的,如果多線程需要加鎖
static ClassName *_instance;
+ (instancetype)sharedInstance{
@synchronized (self) {
if(!_instance) {
_instance = [self alloc]init];
}
}
return _instance;
}
方式二: 注意多線程問題 GCDdispatch_once 默認(rèn)是線程安全的
static ClassName *_instance;
+ (instancetype)sharedInstance{
static dispatch_one_t oneToken;
dispatch_once(&onetoken,^{
_instance = [self alloc]init];
});
return _instance;
}
+ (instancetype)allocWithZone:(NSZone *) zone{
static dispatch_t onetoken;
dispatch_once(&oncetoken ^{
_instance = [super allocwithzone:zone];
})
retun _instance
}
18. 什么是僵尸對象?
- 已經(jīng)被銷毀的對象(不能再使用的對象),內(nèi)存已經(jīng)被回收的對象。
19.野指針
- 指向僵尸對象(不可用內(nèi)存/已經(jīng)釋放的內(nèi)存地址)的指針
比如:
NSObject *obj = [NSObject new];
[obj release]; // obj 指向的內(nèi)存地址已經(jīng)釋放了,
obj 如果再去訪問的話就是野指針錯誤了.
野指針錯誤形式在Xcode中通常表現(xiàn)為:Thread 1:EXC_BAD_ACCESS,因為你訪問了一塊已經(jīng)不屬于你的內(nèi)存。
20. 什么是內(nèi)存泄露?
- 內(nèi)存泄露 :一個對象不再使用,但是這個對象卻沒有被銷毀,空間沒有釋放,則這個就叫做內(nèi)存泄露.
- ARC導(dǎo)致的循環(huán)引用 block,delegate,NSTimer等.
21.數(shù)組copy后里面的元素會復(fù)制一份新的嗎
- 不會,數(shù)組里面存的是之前對象的地址,不會改變,可以自己測試一下
22. 如下代碼,會有什么問題嗎?
@property (copy, nonatomic) NSMutableArray * array
使用 copy 修飾,會生成不可變數(shù)組,在添加刪除數(shù)組元素時候會崩潰
23. OC中的NSInteger 和int 有什么區(qū)別
- 在32位操作系統(tǒng)時候, NSInteger 等價于 int,即32位
- 在64位操作系統(tǒng)時候, NSInteger 等價于 long,即64位
24. @synthesize 和 @dynamic 分別有什么作用
- @property 有兩個對應(yīng)的詞,一個是
@synthesize
,一個是@dynamic
。 - 如果
@synthesize 和@dynamic
都沒寫,那么默認(rèn)的就是@syntheszie var = _var
; -
@synthesize
的語義是如果你沒有手動實現(xiàn)setter
方法和getter
方法,那么編譯器 會自動為你加上這兩個方法 -
@dynamic
告訴編譯器:屬性的setter 與 getter
方法由用戶自己實現(xiàn),不自動生成(當(dāng)然對于 readonly 的屬性只需提供 getter 即可)
25.NSMutableDictionary 中使用setValueForKey 和 setObjectForKey有什么區(qū)別?
- 根據(jù)官方文檔說明: 一般情況下,如果給NSMutableDictionary 發(fā)送
setValue
仍然是調(diào)用了setObject
方法, 如果參數(shù) value 為 nil,則會調(diào)用removeObject
移除這個鍵值對; -
setObjectForKey
是 NSMutableDictionary特有的, value 不能為 nil,否則會崩潰 -
setValueForKey
是KVC的,key 必須是字符串類型, setObject 的 key 可以是任意類型
26.列舉出延遲調(diào)用的幾種方法?
- performSelector方法
[self performSelector:@selector(Delay) withObject:nil afterDelay:3.0f];
- NSTimer定時器
[NSTimer scheduledTimerWithTimeInterval:3.0f target:self selector:@selector(Delay) userInfo:nil repeats:NO];
- sleepForTimeInterval
[NSThread sleepForTimeInterval:3.0f];
- GCD方式
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self Delay];
});
- (void)Delay {
NSLog(@"執(zhí)行");
}
27. NSCache 和NSDictionary 區(qū)別?
- NSCache可以提供自動刪減緩存功能,而且保證線程安全,與字典不同,不會拷貝鍵。
- NSCache可以設(shè)置緩存上限,限制對象個數(shù)和總緩存開銷。定義了刪除緩存對象的時機。這個機制只對NSCache起到指導(dǎo)作用,不會一定執(zhí)行。
- NSPurgeableData搭配NSCache使用,可以自動清除數(shù)據(jù)。
- 只有那種“重新計算很費勁”的數(shù)據(jù)才值得放入緩存。
28.NSArray 和 NSSet區(qū)別
- NSSet和NSArray功能性質(zhì)一樣,用于存儲對象,屬于集合。
- NSSet屬于 “無序集合”,在內(nèi)存中存儲方式是不連續(xù)
- NSArray是 “有序集合” 它內(nèi)存中存儲位置是連續(xù)的。
- NSSet,NSArray都是類,只能添加對象,如果需要加入基本數(shù)據(jù)類型(int,float,BOOL,double等),需要將數(shù)據(jù)封裝成NSNumber類型。
- 由于NSSet是用hash實現(xiàn)的所以就造就了它查詢速度比較快,但是我們不能把某某對象存在第幾個元素后面之類的有關(guān)下標(biāo)的操作。
29.聲明一個函數(shù),傳入值是一個輸入輸出參數(shù)都是 int的 block 函數(shù)
- (void)test_Function:(int(^)(int num)) block{}
30.面向?qū)ο蠛兔嫦蜻^程的區(qū)別?
- 面向過程:注重的是解決問題的步驟,比如C語言
- 面向?qū)ο?關(guān)注的是解決問題的去要那些對象,OC語言就是面向?qū)ο?/li>
31.對象方法和類方法的區(qū)別?
- 對象方法:以減號開頭,只可以被對象調(diào)用,可以訪問成員變量
- 類方法:以加號開頭只能用類名調(diào)用,對象不可以調(diào)用,類方法不能訪問成員變量
32. 什么是面向過程?(POP--Procedure Oriented Programming)
- “面向過程”
(Procedure Oriented)
是一種以過程為中心的編程思想。就是分析出解決問題所需要的步驟,然后用函數(shù)把這些步驟一步一步實現(xiàn),使用的時候一個一個依次調(diào)用就可以了。注重的是實現(xiàn)過程!
33. 什么是面向?qū)ο?(OOP--Object Oriented Programming)
“面向?qū)ο蟆笔且环N以對象為中心的編程思想。
面向?qū)ο蟮娜筇匦裕?/p>
- 封裝
隱藏對象的屬性和實現(xiàn)細節(jié),僅對外提供公共訪問方式,將變化隔離,便于使用,提高復(fù)用性和安全性。 - 繼承
提高代碼復(fù)用性;建立了類之間的關(guān)系;子類可以擁有父類的所有成員變量的方法;繼承是多態(tài)的前提。 - 多態(tài)
父類或接口定義的引用變量可以指向子類或具體實現(xiàn)類的實例對象。提高了程序的拓展性。
- 正因為面向?qū)ο缶幊逃兄N特性,
繼承、封裝、多態(tài)
,從而使得面向?qū)ο缶幊谈哂腥菀鬃屓私邮埽N近與人們的生活,比面向?qū)ο缶幊谈臃奖闩c快捷,一定程度上降低了程序員的工作量,使程序的可讀性也得到了提高,代碼的效率也得到了提高。
34. 什么是多態(tài)?
- 多態(tài)在面向?qū)ο笳Z言中指同一個接口有多種不同的實現(xiàn)方式,在OC中,多態(tài)則是不同對象對同一消息的不同響應(yīng)方式;子類通過重寫父類的方法來改變同一方法的實現(xiàn).體現(xiàn)多態(tài)性
- 通俗來講: 多態(tài)就父類類型的指針指向子類的對象,在函數(shù)(方法)調(diào)用的時候可以調(diào)用到正確版本的函數(shù)(方法)。
- 多態(tài)就是某一類事物的多種形態(tài).繼承是多態(tài)的前提;
35. 什么是分類?
- 分類: 在不修改原有類代碼的情況下,可以給類添加方法
Categroy 給類擴展方法,或者關(guān)聯(lián)屬性, Categroy底層結(jié)構(gòu)也是一個結(jié)構(gòu)體:內(nèi)部存儲這結(jié)構(gòu)體的名字,那個類的分類,以及對象和類方法列表,協(xié)議,屬性信息 - 通過Runtime加載某個類的所有Category數(shù)據(jù)
- 把所有Category的方法、屬性、協(xié)議數(shù)據(jù),合并到一個大數(shù)組中后面參與編譯的Category數(shù)據(jù),會在數(shù)組的前面
- 將合并后的分類數(shù)據(jù)(方法、屬性、協(xié)議),插入到類原來數(shù)據(jù)的前面
36.什么是協(xié)議?
- 協(xié)議:協(xié)議是一套標(biāo)準(zhǔn),這個標(biāo)準(zhǔn)中聲明了很多方法,但是不關(guān)心具體這些方法是怎么實現(xiàn)的,具體實現(xiàn)是由遵循這個協(xié)議的類去完成的。
- 在OC中,一個類可以實現(xiàn)多個協(xié)議,通過協(xié)議可以彌補單繼承的缺陷但是協(xié)議跟繼承不一樣,協(xié)議只是一個方法列表,方法的實現(xiàn)得靠遵循這個協(xié)議的類去實現(xiàn)。
37.正式協(xié)議&非正式協(xié)議?
- 非正式協(xié)議:凡是在NSObject或其子類 Foundation 框架中的類增加類別(分類),都是非正式協(xié)議
- 正式協(xié)議: @protocol
38.如何實現(xiàn)多繼承?
- 類別
- 協(xié)議
- 消息轉(zhuǎn)發(fā) (后面會詳細講述)
39.為什么說OC是一門動態(tài)語言?
- 動態(tài)語言:是指程序在運行時可以改變其結(jié)構(gòu),新的函數(shù)可以被引進,已有的函數(shù)可以被刪除等在結(jié)構(gòu)上的變化
- 動態(tài)類型語言: 就是類型的檢查是在運行時做的。
OC的動態(tài)特性可從三方面:
- 動態(tài)類型(Dynamic typing):最終判定該類的實例類型是在運行期間
- 動態(tài)綁定(Dynamic binding):在運行時確定調(diào)用的方法
- 動態(tài)加載(Dynamic loading):在運行期間加載需要的資源或可執(zhí)行代碼
40.動態(tài)綁定?
- 動態(tài)綁定 將調(diào)用方法的確定也推遲到運行時。OC可以先跳過編譯,到運行的時候才動態(tài)地添加函數(shù)調(diào)用,在運行時才決定要調(diào)用什么方法,需要傳什么參數(shù)進去,這就是動態(tài)綁定。
- 在編譯時,方法的 調(diào)用并不和代碼綁定在一起,只有在消實發(fā)送出來之后,才確定被調(diào)用的代碼。通過動態(tài)類型和動態(tài)綁定技術(shù),
41. cocoa 和 cocoa touch是什么?區(qū)別?
- Cocoa包含F(xiàn)oundation和AppKit框架,可用于開發(fā)Mac OS X系統(tǒng)的應(yīng)用程序。
- Cocoa Touch包含F(xiàn)oundation和UIKit框架,可用于開發(fā)iPhone OS系統(tǒng)的應(yīng)用程序。
- Cocoa是 Mac OS X 的開發(fā)環(huán)境,Cocoa Touch是 iPhone OS的開發(fā)環(huán)境。
42. cocoa touch底層技術(shù)架構(gòu)?
cocoa touch底層技術(shù)架構(gòu) 主要分為4層:
- 可觸摸層 Cocoa Touch : UI組件,觸摸事件和事件驅(qū)動,系統(tǒng)接口
- 媒體層 Media: 音視頻播放,動畫,2D和3D圖形
- Core Server: 核心服務(wù)層,底層特性,文件,網(wǎng)絡(luò),位置服務(wù)區(qū)等
- Core OS: 內(nèi)存管理,底層網(wǎng)絡(luò),硬盤管理
43. 什么是謂詞?
謂詞(NSPredicate
)是OC針對數(shù)據(jù)集合的一種邏輯帥選條件,類似一個過濾器,簡單實實用代碼如下:
Person * p1 = [Person personWithName:@"alex" Age:20];
Person * p2 = [Person personWithName:@"alex1" Age:30];
Person * p3 = [Person personWithName:@"alex2" Age:10];
Person * p4 = [Person personWithName:@"alex3" Age:40];
Person * p5 = [Person personWithName:@"alex4" Age:80];
NSArray * persons = @[p1, p2, p3, p4, p5];
//定義謂詞對象,謂詞對象中包含了過濾條件
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"age < 30"];
//使用謂詞條件過濾數(shù)組中的元素,過濾之后返回查詢的結(jié)果
NSArray *array = [persons filteredArrayUsingPredicate:predicate];
44. 什么是類工廠方法?
類工廠方法就是用來快速創(chuàng)建對象的類方法, 他可以直接返回一個初始化好的對象,具備以下特征:
- 一定是類方法
- 返回值需要是 id/instancetype 類型
- 規(guī)范的方法名說說明類工廠方法返回的是一個什么對象,一般以類名首字母小寫開始;
比如系統(tǒng) UIButton 的buttonWithType 就是一個類工廠方法:
// 類工廠方法
+ (instancetype)buttonWithType:(UIButtonType)buttonType;
// 使用
+ UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
45. 什么是糖衣語法?
糖衣語法又叫做語法糖
或語法鹽
,是指在計算機語言中添加某種語法,這種語法對語言的功能沒有影響,但更方便程序員使用,增加程序的可讀性,減少代碼出錯機會
OC中的字面量,其實就是語法糖
NSNumber * number = @1;
NSArray * array = @[@1, @2, @3];
NSDictionary * dict = @{@"key":@"value"};
NSNumber * num1 = array[0];
NSString * value = dict[@"key"];
46.Svn 和 Git 區(qū)別
svn 和 git 都是用來對項目進行版本控制以及代碼管理的.可以監(jiān)測代碼及資源的更改變化.有利于實現(xiàn)高效的團隊合作;
svn 是集中式的,集中式是指只有一個遠程版本庫,git 是分布式的,分布式有本地和遠程版本庫,本地倉庫都保留了整個項目的完整備份;
如果存儲遠程版本庫的服務(wù)器掛了,所有人的代碼都無法提交,甚至丟失版本庫, git則因為有本地版本庫而不會有這個問題。由于兩者的架構(gòu)不同,git 和 svn 的分支也是不同的, svn 的分支是一個完整的目錄,包含所有的實際文件,和中心倉庫是保持同步的,如果某個團隊成員創(chuàng)建新的分支,那么會同步到所有的版本成員中,所有人都會收到影響. 而 git下創(chuàng)建的分支合并前是不會影響到任何人的.創(chuàng)建分支可以在本地脫機進行任何操作.測試無誤后在合并到主分支,然后其他成員才可以看得到.
47.OC中有二維數(shù)組嗎? 如何實現(xiàn)?
OC中沒有二維數(shù)組, 可以通過一維數(shù)組嵌套來實現(xiàn)二維數(shù)組;
// 字面量定義
NSArray * array = @[
@[@1,@2,@3,@4,@5],
@[@11,@12,@13,@14,@15],
@[@21,@22,@23,@24,@25],
@[@31,@32,@33,@34,@35],
@[@41,@42,@43,@44,@45],
];
// 訪問
NSLog(@"%@",array[1][1]);
48.CocoaPods理解
CocoaPods 是一個 objc 的依賴管理工具,而其本身是利用 ruby 的依賴管理 gem 進行構(gòu)建的
- 想深入了解這個命令執(zhí)行的詳細內(nèi)容,可以在這個命令后面加上 --verbose。現(xiàn)在運行這個命令 pod install --verbose
- CocoaPod三方庫,會優(yōu)先編譯
49. --verbose 和 --no-repo-update有什么用?
- verbose意思為 冗長的、啰嗦的,一般在程序中表示詳細信息。此參數(shù)可以顯示命令執(zhí)行過程中都發(fā)生了什么。
- pod install或pod update可能會卡在Analyzing dependencies步驟,因為這兩個命令會升級 CocoaPods 的 spec 倉庫,追加該參數(shù)可以省略此步驟,命令執(zhí)行速度會提升。
50. KVC中的集合運算符
- 簡單集合運算符:@avg、@sum、@max、@min、@count (只能用在集合對象中,對象屬性必須為數(shù)字類型)
- 對象操作符:
@unionOfObjects:返回指定屬性的值的數(shù)組,不去重
@distinctUnionOfObjects:返回指定屬性去重后的值的數(shù)組 - 數(shù)組 / 集體操作符:跟對象操作符很相似,只不過是在NSArray和NSSet所組成的集合中工作的。@unionOfArrays:返回一個數(shù)組,值由各個子數(shù)組的元素組成,不去重 @distinctUnionOfArrays:返回一個數(shù)組,值由各個子數(shù)組的元素組成,去重 @distinctUnionOfSets:和@distinctUnionOfArrays差不多, 只是它期望的是一個包含著NSSet對象的NSSet,并且會返回一個NSSet對象。因為集合不能有重復(fù)的值,所以只有distinct操作。
51.簡要說明const,宏,static,extern區(qū)分以及使用?
const
const常量修飾符,經(jīng)常使用的字符串常量,一般是抽成宏,但是蘋果不推薦我們抽成宏,推薦我們使用const常量。
- const 作用:限制類型
- 使用const修飾基本變量, 兩種寫法效果一致 , b都是只讀變量
const int b = 5;
int const b = 5;
- 使用const修飾指針變量的變量
第一種: const int *p = &a 和 int const *q = &a; 效果一致,*p 的值不能改,p 的指向可以改;
第二種: int * const p = &a; 表示 p 的指向不能改,*p 的值可以改
第三種:
const int * const p = &a; *p 值和 p 的指向都不能改
const 在*左邊, 指向可變, 值不可變
const 在*的右邊, 指向不可變, 值可變
const 在*的兩邊, 都不可變
宏
* 基本概念:宏是一種批量處理的稱謂。一般說來,宏是一種規(guī)則或模式,或稱語法替換 ,用于說明某一特定輸入(通常是字符串)如何根據(jù)預(yù)定義的規(guī)則轉(zhuǎn)換成對應(yīng)的輸出(通常也是字符串)。這種替換在預(yù)編譯時進行,稱作宏展開。編譯器會在編譯前掃描代碼,如果遇到我們已經(jīng)定義好的宏那么就會進行代碼替換,宏只會在內(nèi)存中copy一份,然后全局替換,宏一般分為對象宏和函數(shù)宏。 宏的弊端:如果代碼中大量的使用宏會使預(yù)編譯時間變長。
const與宏的區(qū)別?
* 編譯檢查 宏沒有編譯檢查,const有編譯檢查;
* 宏的好處 定義函數(shù),方法 const不可以;
* 宏的壞處 大量使用宏,會導(dǎo)致預(yù)編譯時間過長
static
* 修飾局部變量: 被static修飾局部變量,延長生命周期,跟整個應(yīng)用程序有關(guān),程序結(jié)束才會銷毀,被 static 修飾局部變量,只會分配一次內(nèi)存
* 修飾全局變量: 被static修飾全局變量,作用域會修改,也就是只能在當(dāng)前文件下使用
extern
聲明外部全局變量(只能用于聲明,不能用于定義)
常用用法(.h結(jié)合extern聯(lián)合使用)
如果在.h文件中聲明了extern全局變量,那么在同一個類中的.m文件對全局變量的賦值必須是:數(shù)據(jù)類型+變量名(與聲明一致)=XXXX結(jié)構(gòu)。并且在調(diào)用的時候,必須導(dǎo)入.h文件。代碼如下:
.h
@interface ExternModel : NSObject
extern NSString *lhString;
@end
.m
@implementation ExternModel
NSString *lhString=@"hello";
@end
調(diào)用的時候:例如:在viewController.m中調(diào)用,則可以引入:ExternModel.h,否則無法識別全局變量。當(dāng)然也可以通過不導(dǎo)入頭文件的方式進行調(diào)用(通過extern調(diào)用)。
52.編譯型和解釋型的區(qū)別?
- 編譯型語言: 首先是將源代碼編譯生成機器指令,再由機器運行機器碼 (二進制)。
- 解釋型語言: 源代碼不是直接翻譯成機器指令,而是先翻譯成中間代碼,再由解釋器對中間代碼進行解釋運行。
53.動態(tài)語言和靜態(tài)語言?
- 動態(tài)類型語言: 是指數(shù)據(jù)類型的檢查是在運行時做的。用動態(tài)類型語言編程時,不用給變量指定數(shù)據(jù)類型,該語言會在你第一次賦值給變量時,在內(nèi)部記錄數(shù)據(jù)類型。
- 靜態(tài)類型語言: 是指數(shù)據(jù)類型的檢查是在運行前(如編譯階段)做的。
54.什么是指針常量和常量指針?
常量指針本質(zhì)是指針,常量修飾它,表示這個指針乃是一個指向常量的指針(變量)。
指針指向的對象是常量,那么這個對象不能被更改。指針常量的本質(zhì)是一個常量,而用指針修飾它,那么說明這個常量的值應(yīng)該是一個指針。
指針常量的值是指針,這個值因為是常量,所以不能被賦值
55. 指針函數(shù)和函數(shù)指針
指針函數(shù)
- 指針函數(shù): 顧名思義,它的本質(zhì)是一個函數(shù),不過它的返回值是一個指針。
// 指針函數(shù)
int *sum(int a, int b){
int result = a + b;
int *c = &result;
return c;
}
int *p = sum(10, 20);
printf("sum:%d\n", *p);
函數(shù)指針
- 與指針函數(shù)不同,函數(shù)指針 的本質(zhì)是一個指針,該指針的地址指向了一個函數(shù),所以它是指向函數(shù)的指針。
// 函數(shù)指針
int max(int a, int b){
return (a > b)?a:b;
}
int (*p)(int, int) = max;
int result = p(10, 20);
printf("result:%d\n", result);
56.寫一個標(biāo)準(zhǔn)的宏MAX,這個宏輸入2個參數(shù),返回最大一個
#define Max(a,b) a>b?a:b
57.自定義宏 #define MIN(A,B) A<B?A:B 代碼運行結(jié)果?
float a = 1;
float b = MIN(a++,1.5);
問 a= ? b = ?
答案: a = 3; b = 2
a++ 會后執(zhí)行, a++在表達式出現(xiàn)了2次,得3, a++<1.5,返回a++,得2
// 擴展
float a = 1;
float b = [self getMax:a++ b:1.5];
- (CGFloat)getMax:(CGFloat ) a b:(CGFloat)b{
return a>b?a:b;
}
運行 a = 2; b =1.5;