iOS最新面試題匯總:
iOS最新面試題匯總(一)
iOS最新面試題匯總(二)
iOS最新面試題匯總(三)
iOS最新面試題匯總(四)
1. 設(shè)計(jì)模式是什么? 你知道哪些設(shè)計(jì)模式,并簡要敘述?
設(shè)計(jì)模式是一種編碼經(jīng)驗(yàn),就是用比較成熟的邏輯去處理某一種類型的事情。
1). MVC模式:Model View Control,把模型 視圖 控制器 層進(jìn)行解耦合編寫。
2). MVVM模式:Model View ViewModel 把模型 視圖 業(yè)務(wù)邏輯 層進(jìn)行解耦和編寫。
3). 單例模式:通過static關(guān)鍵詞,聲明全局變量。在整個(gè)進(jìn)程運(yùn)行期間只會被賦值一次。
4). 觀察者模式:KVO是典型的通知模式,觀察某個(gè)屬性的狀態(tài),狀態(tài)發(fā)生變化時(shí)通知觀察者。
5). 委托模式:代理+協(xié)議的組合。實(shí)現(xiàn)1對1的反向傳值操作。
6). 工廠模式:通過一個(gè)類方法,批量的根據(jù)已有模板生產(chǎn)對象。
2. MVC 和 MVVM 的區(qū)別
1). MVVM是對胖模型進(jìn)行的拆分,其本質(zhì)是給控制器減負(fù),將一些弱業(yè)務(wù)邏輯放到VM中去處理。
2). MVC是一切設(shè)計(jì)的基礎(chǔ),所有新的設(shè)計(jì)模式都是基于MVC進(jìn)行的改進(jìn)。
3. #import跟 #include 有什么區(qū)別,@class呢,#import<> 跟 #import””有什么區(qū)別?
答:
1). #import是Objective-C導(dǎo)入頭文件的關(guān)鍵字,#include是C/C++導(dǎo)入頭文件的關(guān)鍵字,使用#import頭文件會自動(dòng)只導(dǎo)入一次,不會重復(fù)導(dǎo)入。
2). @class告訴編譯器某個(gè)類的聲明,當(dāng)執(zhí)行時(shí),才去查看類的實(shí)現(xiàn)文件,可以解決頭文件的相互包含。
3). #import<>用來包含系統(tǒng)的頭文件,#import””用來包含用戶頭文件。
4.frame 和 bounds 有什么不同?
frame指的是:該view在父view坐標(biāo)系統(tǒng)中的位置和大小。(參照點(diǎn)是父view的坐標(biāo)系統(tǒng))
bounds指的是:該view在本身坐標(biāo)系統(tǒng)中的位置和大小。(參照點(diǎn)是本身坐標(biāo)系統(tǒng))
5. Objective-C的類可以多重繼承么?可以實(shí)現(xiàn)多個(gè)接口么?Category是什么?重寫一個(gè)類的方式用繼承好還是分類好?為什么?
答:Objective-C的類不可以多重繼承;可以實(shí)現(xiàn)多個(gè)接口(協(xié)議);Category是類別;一般情況用分類好,用Category去重寫類的方法,僅對本Category有效,不會影響到其他類與原有類的關(guān)系。
6. @property 的本質(zhì)是什么?ivar、getter、setter 是如何生成并添加到這個(gè)類中的
@property 的本質(zhì)是什么?
@property = ivar + getter + setter;
“屬性” (property)有兩大概念:ivar(實(shí)例變量)、getter+setter(存取方法)
“屬性” (property)作為 Objective-C 的一項(xiàng)特性,主要的作用就在于封裝對象中的數(shù)據(jù)。 Objective-C 對象通常會把其所需要的數(shù)據(jù)保存為各種實(shí)例變量。實(shí)例變量一般通過“存取方法”(access method)來訪問。其中,“獲取方法” (getter)用于讀取變量值,而“設(shè)置方法” (setter)用于寫入變量值。
7.@property中有哪些屬性關(guān)鍵字?/ @property 后面可以有哪些修飾符?
屬性可以擁有的特質(zhì)分為四類:
1.原子性--- nonatomic 特質(zhì)
2.讀/寫權(quán)限---readwrite(讀寫)、readonly (只讀)
3.內(nèi)存管理語義---assign、strong、 weak、unsafe_unretained、copy
4.方法名---getter=<name> 、setter=<name>
5.不常用的:nonnull,null_resettable,nullable
屬性關(guān)鍵字
8.readwrite,readonly,assign,retain,copy,nonatomic 各是什么作用,在那種情況下用?
答:
1). readwrite 是可讀可寫特性。需要生成getter方法和setter方法。
2). readonly 是只讀特性。只會生成getter方法,不會生成setter方法,不希望屬性在類外改變。
3). assign 是賦值特性。setter方法將傳入?yún)?shù)賦值給實(shí)例變量;僅設(shè)置變量時(shí),assign用于基本數(shù)據(jù)類型。
4). retain(MRC)/strong(ARC) 表示持有特性。setter方法將傳入?yún)?shù)先保留,再賦值,傳入?yún)?shù)的retaincount會+1。
5). copy 表示拷貝特性。setter方法將傳入對象復(fù)制一份,需要完全一份新的變量時(shí)。
6). nonatomic 非原子操作。決定編譯器生成的setter和getter方法是否是原子操作,atomic表示多線程安全,一般使用nonatomic,效率高。
9. 什么情況使用 weak 關(guān)鍵字,相比 assign 有什么不同?
1.在 ARC 中,在有可能出現(xiàn)循環(huán)引用的時(shí)候,往往要通過讓其中一端使用 weak 來解決,比如: delegate 代理屬性。
2.自身已經(jīng)對它進(jìn)行一次強(qiáng)引用,沒有必要再強(qiáng)引用一次,此時(shí)也會使用 weak,自定義 IBOutlet 控件屬性一般也使用 weak;當(dāng)然,也可以使用strong。
IBOutlet連出來的視圖屬性為什么可以被設(shè)置成weak?
因?yàn)楦缚丶膕ubViews數(shù)組已經(jīng)對它有一個(gè)強(qiáng)引用。
不同點(diǎn):
assign 可以用非 OC 對象,而 weak 必須用于 OC 對象。
weak 表明該屬性定義了一種“非擁有關(guān)系”。在屬性所指的對象銷毀時(shí),屬性值會自動(dòng)清空(nil)。
10. 怎么用 copy 關(guān)鍵字?
用途:
- NSString、NSArray、NSDictionary 等等經(jīng)常使用copy關(guān)鍵字,是因?yàn)樗麄冇袑?yīng)的可變類型:NSMutableString、NSMutableArray、NSMutableDictionary;
- block 也經(jīng)常使用 copy 關(guān)鍵字。
說明:
block 使用 copy 是從 MRC 遺留下來的“傳統(tǒng)”,在 MRC 中,方法內(nèi)部的 block 是在棧區(qū)的,使用 copy 可以把它放到堆區(qū).在 ARC 中寫不寫都行:對于 block 使用 copy 還是 strong 效果是一樣的,但寫上 copy 也無傷大雅,還能時(shí)刻提醒我們:編譯器自動(dòng)對 block 進(jìn)行了 copy 操作。如果不寫 copy ,該類的調(diào)用者有可能會忘記或者根本不知道“編譯器會自動(dòng)對 block 進(jìn)行了 copy 操作”,他們有可能會在調(diào)用之前自行拷貝屬性值。這種操作多余而低效。
11. 用@property聲明的 NSString / NSArray / NSDictionary 經(jīng)常使用 copy 關(guān)鍵字,為什么?如果改用strong關(guān)鍵字,可能造成什么問題?
答:用 @property 聲明 NSString、NSArray、NSDictionary 經(jīng)常使用 copy 關(guān)鍵字,是因?yàn)樗麄冇袑?yīng)的可變類型:NSMutableString、NSMutableArray、NSMutableDictionary,他們之間可能進(jìn)行賦值操作(就是把可變的賦值給不可變的),為確保對象中的字符串值不會無意間變動(dòng),應(yīng)該在設(shè)置新屬性值時(shí)拷貝一份。
- 因?yàn)楦割愔羔樋梢灾赶蜃宇悓ο?使用 copy 的目的是為了讓本對象的屬性不受外界影響,使用 copy 無論給我傳入是一個(gè)可變對象還是不可對象,我本身持有的就是一個(gè)不可變的副本。
- 如果我們使用是 strong ,那么這個(gè)屬性就有可能指向一個(gè)可變對象,如果這個(gè)可變對象在外部被修改了,那么會影響該屬性。
- 總結(jié):使用copy的目的是,防止把可變類型的對象賦值給不可變類型的對象時(shí),可變類型對象的值發(fā)送變化會無意間篡改不可變類型對象原來的值。
12. 淺拷貝和深拷貝的區(qū)別?
答:
淺拷貝:只復(fù)制指向?qū)ο蟮闹羔槪粡?fù)制引用對象本身。
深拷貝:復(fù)制引用對象本身。內(nèi)存中存在了兩份獨(dú)立對象本身,當(dāng)修改A時(shí),A_copy不變。
13.系統(tǒng)對象的 copy 與 mutableCopy 方法
不管是集合類對象(NSArray、NSDictionary、NSSet ... 之類的對象),還是非集合類對象(NSString, NSNumber ... 之類的對象),接收到copy和mutableCopy消息時(shí),都遵循以下準(zhǔn)則:
- copy 返回的是不可變對象(immutableObject);如果用copy返回值調(diào)用mutable對象的方法就會crash。
- mutableCopy 返回的是可變對象(mutableObject)。
一、非集合類對象的copy與mutableCopy
在非集合類對象中,對不可變對象進(jìn)行copy操作,是指針復(fù)制,mutableCopy操作是內(nèi)容復(fù)制;
對可變對象進(jìn)行copy和mutableCopy都是內(nèi)容復(fù)制。用代碼簡單表示如下:
NSString *str = @"hello word!";
NSString *strCopy = [str copy] // 指針復(fù)制,strCopy與str的地址一樣
NSMutableString *strMCopy = [str mutableCopy] // 內(nèi)容復(fù)制,strMCopy與str的地址不一樣
NSMutableString *mutableStr = [NSMutableString stringWithString: @"hello word!"];
NSString *strCopy = [mutableStr copy] // 內(nèi)容復(fù)制
NSMutableString *strMCopy = [mutableStr mutableCopy] // 內(nèi)容復(fù)制
二、集合類對象的copy與mutableCopy (同上)
在集合類對象中,對不可變對象進(jìn)行copy操作,是指針復(fù)制,mutableCopy操作是內(nèi)容復(fù)制;
對可變對象進(jìn)行copy和mutableCopy都是內(nèi)容復(fù)制。但是:集合對象的內(nèi)容復(fù)制僅限于對象本身,對集合內(nèi)的對象元素仍然是指針復(fù)制。(即單層內(nèi)容復(fù)制)
NSArray *arr = @[@[@"a", @"b"], @[@"c", @"d"];
NSArray *copyArr = [arr copy]; // 指針復(fù)制
NSMutableArray *mCopyArr = [arr mutableCopy]; //單層內(nèi)容復(fù)制
NSMutableArray *array = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];
NSArray *copyArr = [mutableArr copy]; // 單層內(nèi)容復(fù)制
NSMutableArray *mCopyArr = [mutableArr mutableCopy]; // 單層內(nèi)容復(fù)制
【總結(jié)一句話】:
只有對不可變對象進(jìn)行copy操作是指針復(fù)制(淺復(fù)制),其它情況都是內(nèi)容復(fù)制(深復(fù)制)!
14.這個(gè)寫法會出什么問題:@property (nonatomic, copy) NSMutableArray *arr;
問題:添加,刪除,修改數(shù)組內(nèi)的元素的時(shí)候,程序會因?yàn)檎也坏綄?yīng)的方法而崩潰。
//如:-[__NSArrayI removeObjectAtIndex:]: unrecognized selector sent to instance 0x7fcd1bc30460
// copy后返回的是不可變對象(即 arr 是 NSArray 類型,NSArray 類型對象不能調(diào)用 NSMutableArray 類型對象的方法)
原因:是因?yàn)?copy 就是復(fù)制一個(gè)不可變 NSArray 的對象,不能對 NSArray 對象進(jìn)行添加/修改。
15. 如何讓自己的類用 copy 修飾符?如何重寫帶 copy 關(guān)鍵字的 setter?
若想令自己所寫的對象具有拷貝功能,則需實(shí)現(xiàn) NSCopying 協(xié)議。如果自定義的對象分為可變版本與不可變版本,那么就要同時(shí)實(shí)現(xiàn) NSCopying 與 NSMutableCopying 協(xié)議。
具體步驟:
- 需聲明該類遵從 NSCopying 協(xié)議
- 實(shí)現(xiàn) NSCopying 協(xié)議的方法。
// 該協(xié)議只有一個(gè)方法: - (id)copyWithZone:(NSZone *)zone;
// 注意:使用 copy 修飾符,調(diào)用的是copy方法,其實(shí)真正需要實(shí)現(xiàn)的是 “copyWithZone” 方法。
16.寫一個(gè) setter 方法用于完成 @property (nonatomic, retain) NSString *name,寫一個(gè) setter 方法用于完成 @property (nonatomic, copy) NSString *name
答:
// retain
-(void)setName:(NSArray *)name
{
if (_name !=name) {
[_name release];
_name =[name retain];
}
}
// copy
-(void)setName:(NSString *)name
{
if (_name !=name) {
[_name release];
_name = [name copy];
}
}
17. @synthesize 和 @dynamic 分別有什么作用?
@property有兩個(gè)對應(yīng)的詞,一個(gè)是@synthesize(合成實(shí)例變量),一個(gè)是@dynamic。
如果@synthesize和@dynamic都沒有寫,那么默認(rèn)的就是 @synthesize var = _var;
// 在類的實(shí)現(xiàn)代碼里通過 @synthesize 語法可以來指定實(shí)例變量的名字。(@synthesize var = _newVar;)
- @synthesize 的語義是如果你沒有手動(dòng)實(shí)現(xiàn)setter方法和getter方法,那么編譯器會自動(dòng)為你加上這兩個(gè)方法。
- @dynamic 告訴編譯器,屬性的setter與getter方法由用戶自己實(shí)現(xiàn),不自動(dòng)生成(如,@dynamic var)。
18.常見的 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的子類,當(dāng)然也不是NSObject的子類。NSInteger是基本數(shù)據(jù)類型Int或者Long的別名(NSInteger的定義typedef long NSInteger),它的區(qū)別在于,NSInteger會根據(jù)系統(tǒng)是32位還是64位來決定是本身是int還是long。
19.id 聲明的對象有什么特性?
答:id 聲明的對象具有運(yùn)行時(shí)的特性,即可以指向任意類型的Objcetive-C的對象。
20.Objective-C 如何對內(nèi)存管理的,說說你的看法和解決方法?
答:Objective-C的內(nèi)存管理主要有三種方式ARC(自動(dòng)內(nèi)存計(jì)數(shù))、手動(dòng)內(nèi)存計(jì)數(shù)、內(nèi)存池。
1). 自動(dòng)內(nèi)存計(jì)數(shù)ARC:由Xcode自動(dòng)在App編譯階段,在代碼中添加內(nèi)存管理代碼。
2). 手動(dòng)內(nèi)存計(jì)數(shù)MRC:遵循內(nèi)存誰申請、誰釋放;誰添加,誰釋放的原則。
3). 內(nèi)存釋放池Release Pool:把需要釋放的內(nèi)存統(tǒng)一放在一個(gè)池子中,當(dāng)池子被抽干后(drain),池子中所有的內(nèi)存空間也被自動(dòng)釋放掉。內(nèi)存池的釋放操作分為自動(dòng)和手動(dòng)。自動(dòng)釋放受runloop機(jī)制影響。
聯(lián)系
github地址:https://github.com/meetly
希望大家多多指教!