2016-03-03 14:53:59 26320瀏覽
在現(xiàn)如今,隨著移動(dòng)互聯(lián)網(wǎng)科技不斷的發(fā)展和創(chuàng)新,如今無(wú)論是公司還是開(kāi)發(fā)者或設(shè)計(jì)師個(gè)人而言,面試都是一項(xiàng)耗時(shí)耗錢(qián)的項(xiàng)目,而面對(duì)iOS開(kāi)發(fā)者及設(shè)計(jì)師在面試時(shí)可能會(huì)遇到的問(wèn)題進(jìn)行了篩選與匯總。下面我們一起來(lái)一下吧。
1、簡(jiǎn)述OC中內(nèi)存管理機(jī)制。與retain配對(duì)使用的方法是dealloc還是release,為什么?需要與alloc配對(duì)使用的方法是dealloc還是release,為什么?readwrite,readonly,assign,retain,copy,nonatomic 、atomic、strong、weak屬性的作用?
管理機(jī)制:使用了一種叫做引用計(jì)數(shù)的機(jī)制來(lái)管理內(nèi)存中的對(duì)象。OC中每個(gè)對(duì)象都對(duì)應(yīng)著他們自己的引用計(jì)數(shù),引用計(jì)數(shù)可以理解為一個(gè)整數(shù)計(jì)數(shù)器,當(dāng)使用alloc方法創(chuàng)建對(duì)象的時(shí)候,持有計(jì)數(shù)會(huì)自動(dòng)設(shè)置為1。當(dāng)你向一個(gè)對(duì)象發(fā)送retain消息 時(shí),持有計(jì)數(shù)數(shù)值會(huì)增加1。相反,當(dāng)你像一個(gè)對(duì)象發(fā)送release消息時(shí),持有計(jì)數(shù)數(shù)值會(huì)減小1。當(dāng)對(duì)象的持有計(jì)數(shù)變?yōu)?的時(shí)候,對(duì)象會(huì)釋放自己所占用的內(nèi)存。
retain(引用計(jì)數(shù)加1)->release(引用計(jì)數(shù)減1)
alloc(申請(qǐng)內(nèi)存空間)->dealloc(釋放內(nèi)存空間)
readwrite: 表示既有g(shù)etter,也有setter (默認(rèn))
readonly: 表示只有g(shù)etter,沒(méi)有setter
nonatomic:不考慮線程安全
atomic:線程操作安全 (默認(rèn))
線程安全情況下的setter和getter:
- (NSString*) value {
@synchronized(self) {
return [[_value retain] autorelease];
}}
(void) setValue:(NSString*)aValue {
@synchronized(self) {
[aValue retain];
[_value release];
_value = aValue;
} }
retain: release舊的對(duì)象,將舊對(duì)象的值賦予輸入對(duì)象,再提高輸入對(duì)象的索引計(jì)數(shù)為1
assign: 簡(jiǎn)單賦值,不更改索引計(jì)數(shù) (默認(rèn))
copy: 其實(shí)是建立了一個(gè)相同的對(duì)象,地址不同(retain:指針拷貝 copy:內(nèi)容拷貝)
strong:(ARC下的)和(MRC)retain一樣 (默認(rèn))
weak:(ARC下的)和(MRC)assign一樣, weak當(dāng)指向的內(nèi)存釋放掉后自動(dòng)nil化,防止野指針
unsafe_unretained 聲明一個(gè)弱應(yīng)用,但是不會(huì)自動(dòng)nil化,也就是說(shuō),如果所指向的內(nèi)存區(qū)域被釋放了,這個(gè)指針就是一個(gè)野指針了。?autoreleasing 用來(lái)修飾一個(gè)函數(shù)的參數(shù),這個(gè)參數(shù)會(huì)在函數(shù)返回的時(shí)候被自動(dòng)釋放。
2、類(lèi)變量的@protected ,@private,@public,@package,聲明各有什么含義?
@private:作用范圍只能在自身類(lèi)
@protected:作用范圍在自身類(lèi)和繼承自己的子類(lèi) (默認(rèn))
@public:作用范圍最大,可以在任何地方被訪問(wèn)。
@package:這個(gè)類(lèi)型最常用于框架類(lèi)的實(shí)例變量,同一包內(nèi)能用,跨包就不能訪問(wèn)
3、線程是什么?進(jìn)程是什么?二者有什么區(qū)別和聯(lián)系?
一個(gè)程序至少有一個(gè)進(jìn)程,一個(gè)進(jìn)程至少有一個(gè)線程:
進(jìn)程:一個(gè)程序的一次運(yùn)行,在執(zhí)行過(guò)程中擁有獨(dú)立的內(nèi)存單元,而多個(gè)線程共享一塊內(nèi)存
線程:線程是指進(jìn)程內(nèi)的一個(gè)執(zhí)行單元。
聯(lián)系:線程是進(jìn)程的基本組成單位
區(qū)別:(1)調(diào)度:線程作為調(diào)度和分配的基本單位,進(jìn)程作為擁有資源的基本單位? (2)并發(fā)性:不僅進(jìn)程之間可以并發(fā)執(zhí)行,同一個(gè)進(jìn)程的多個(gè)線程之間也可并發(fā)執(zhí)行? (3)擁有資源:進(jìn)程是擁有資源的一個(gè)獨(dú)立單位,線程不擁有系統(tǒng)資源,但可以訪問(wèn)隸屬于進(jìn)程的資源.? (4)系統(tǒng)開(kāi)銷(xiāo):在創(chuàng)建或撤消進(jìn)程時(shí),由于系統(tǒng)都要為之分配和回收資源,導(dǎo)致系統(tǒng)的開(kāi)銷(xiāo)明顯大于創(chuàng)建或撤消線程時(shí)的開(kāi)銷(xiāo)。
舉例說(shuō)明:操作系統(tǒng)有多個(gè)軟件在運(yùn)行(QQ、office、音樂(lè)等),這些都是一個(gè)個(gè)進(jìn)程,而每個(gè)進(jìn)程里又有好多線程(比如QQ,你可以同時(shí)聊天,發(fā)送文件等)
4、談?wù)勀銓?duì)多線程開(kāi)發(fā)的理解?ios中有幾種實(shí)現(xiàn)多線程的方法?
好處:
1.使用線程可以把占據(jù)時(shí)間長(zhǎng)的程序中的任務(wù)放到后臺(tái)去處理
2.用戶(hù)界面可以更加吸引人,這樣比如用戶(hù)點(diǎn)擊了一個(gè)按鈕去觸發(fā)某些事件的處理,可以彈出一個(gè)進(jìn)度條來(lái)顯示處理的進(jìn)度
3.程序的運(yùn)行速度可能加快
4·在一些等待的任務(wù)實(shí)現(xiàn)上如用戶(hù)輸入、文件讀寫(xiě)和網(wǎng)絡(luò)收發(fā)數(shù)據(jù)等,線程就比較有用了。
缺點(diǎn):
1.如果有大量的線程,會(huì)影響性能,因?yàn)椴僮飨到y(tǒng)需要在它們之間切換。
2.更多的線程需要更多的內(nèi)存空間。
3.線程的中止需要考慮其對(duì)程序運(yùn)行的影響。
4.通常塊模型數(shù)據(jù)是在多個(gè)線程間共享的,需要防止線程死鎖情況的發(fā)生。
實(shí)現(xiàn)多線程的方法:
NSObject類(lèi)方法
NSThread
NSOperation
GCD
5、線程同步和異步的區(qū)別?IOS中如何實(shí)現(xiàn)多線程的同步?
異步:舉個(gè)簡(jiǎn)單的例子 就是游戲,游戲會(huì)有圖像和背景音樂(lè)
同步:是指一個(gè)線程要等待上一個(gè)線程執(zhí)行完之后才開(kāi)始執(zhí)行當(dāng)前的線程,上廁所
NSOperationQueue:maxcurrentcount
NSConditionLock
6、假設(shè)有一個(gè)字符串a(chǎn)abcad,請(qǐng)寫(xiě)一段程序,去掉字符串中不相鄰的重復(fù)字符串,即上述字符串處理之后的輸出結(jié)果為:aabcd
NSMutableString * str = [[NSMutableString alloc]initWithFormat;@“aabcad”];
for (int i = 0 ,i < str.length - 1 ;i++){
unsigned char a = [str characterAtIndex:i];
for (int j = i + 1 ,j < str.length ,j++){
unsigned char b = [str characterAtIndex:j];
if (a == b ){
if (j == i + 1){
}else{
[str deleteCharactersInRange:NSMakeRange(j, 1)];
}
}
}
}
NSLog(@“%@”,str);
7、獲取一臺(tái)設(shè)備唯一標(biāo)識(shí)的方法有哪些?
(1)UDID
(2)UUID
(3)MAC Address
(4)OPEN UDID
(5)廣告標(biāo)識(shí)符
(6)Vindor標(biāo)示符
8、iOS類(lèi)是否可以多繼承?如果沒(méi)有,那可以用其他方法實(shí)現(xiàn)嗎?簡(jiǎn)述實(shí)現(xiàn)過(guò)程。
不可以多繼承 用protocol實(shí)現(xiàn)
9、堆和棧的區(qū)別?
堆需要用戶(hù)手動(dòng)釋放內(nèi)存,而棧則是編譯器自動(dòng)釋放內(nèi)存
問(wèn)題擴(kuò)展:要知道OC中NSString的內(nèi)存存儲(chǔ)方式
10、iOS本地?cái)?shù)據(jù)存儲(chǔ)都有哪幾種方式?
NSKeyedArchiver
NSUserDefaults
Write寫(xiě)入方式
SQLite3
(問(wèn)題擴(kuò)展:什么情況下使用什么樣的數(shù)據(jù)存儲(chǔ))
1.NSKeyedArchiver:采用歸檔的形式來(lái)保存數(shù)據(jù),數(shù)據(jù)對(duì)象需要遵守NSCoding協(xié)議,對(duì)象對(duì)應(yīng)的類(lèi)必須提供encodeWithCoder:和initWithCoder:方法。缺點(diǎn):只能一次性歸檔保存以及一次性解壓。所以只能針對(duì)小量數(shù)據(jù),對(duì)數(shù)據(jù)操作比較笨拙,如果想改動(dòng)數(shù)據(jù)的某一小部分,需要解壓或歸檔整個(gè)數(shù)據(jù)。
2.NSUserDefaults:用來(lái)保存應(yīng)用程序設(shè)置和屬性、用戶(hù)保存的數(shù)據(jù)。用戶(hù)再次打開(kāi)程序或開(kāi)機(jī)后這些數(shù)據(jù)仍然存在。NSUserDefaults可以存儲(chǔ)的數(shù)據(jù)類(lèi)型包括:NSData、NSString、NSNumber、NSDate、NSArray、NSDictionary。缺點(diǎn):如果要存儲(chǔ)其他類(lèi)型,需要轉(zhuǎn)換為前面的類(lèi)型,才能用NSUserDefaults存儲(chǔ)。
3.Write寫(xiě)入方式:永久保存在磁盤(pán)中。第一步:獲得文件即將保存的路徑:第二步:生成在該路徑下的文件:第三步:往文件中寫(xiě)入數(shù)據(jù):最后:從文件中讀出數(shù)據(jù):
4. SQLite:采用SQLite數(shù)據(jù)庫(kù)來(lái)存儲(chǔ)數(shù)據(jù)。SQLite作為一中小型數(shù)據(jù)庫(kù),應(yīng)用ios中,跟前三種保存方式相比,相對(duì)比較復(fù)雜一些。
11、寫(xiě)出方法獲取iOS內(nèi)存使用情況。
// 獲取當(dāng)前設(shè)備可用內(nèi)存及所占內(nèi)存的頭文件
#import
#import
// 獲取當(dāng)前設(shè)備可用內(nèi)存(單位:MB)
- (double)availableMemory
{
vm_statistics_data_t vmStats;
mach_msg_type_number_t infoCount = HOST_VM_INFO_COUNT;
kern_return_t kernReturn = host_statistics(mach_host_self(),
HOST_VM_INFO,
(host_info_t)&vmStats,
&infoCount);
if (kernReturn != KERN_SUCCESS) {
return NSNotFound;
}
return ((vm_page_size *vmStats.free_count) / 1024.0) / 1024.0;
}
// 獲取當(dāng)前任務(wù)所占用的內(nèi)存(單位:MB)
- (double)usedMemory
{
task_basic_info_data_t taskInfo;
mach_msg_type_number_t infoCount = TASK_BASIC_INFO_COUNT;
kern_return_t kernReturn = task_info(mach_task_self(),
TASK_BASIC_INFO,
(task_info_t)&taskInfo,
&infoCount);
if (kernReturn != KERN_SUCCESS
) {
return NSNotFound;
}
return taskInfo.resident_size / 1024.0 / 1024.0;
}
12、什么是安全釋放?
置nil 再釋放
13、寫(xiě)一個(gè)標(biāo)準(zhǔn)宏MIN,這個(gè)宏輸入兩個(gè)參數(shù)并返回較小的一個(gè)?
#define MIN(X,Y) ((X)>(Y)?(Y):(X))
擴(kuò)展:在定義宏的時(shí)候需要注意哪些問(wèn)題?
宏全部大寫(xiě) 寫(xiě)在#import 下 @interface上 結(jié)尾無(wú)分號(hào)
14、iphone os有沒(méi)有垃圾回收機(jī)制?簡(jiǎn)單闡述一下OC內(nèi)存管理。
iphone os沒(méi)有垃圾回收機(jī)制 oc的內(nèi)存管理是誰(shuí)創(chuàng)建誰(shuí)釋放 程序中遇到retain 該對(duì)象引用計(jì)數(shù)+1 遇release該對(duì)象引用計(jì)數(shù)-1 retainCount為0時(shí) 內(nèi)存釋放
15、簡(jiǎn)述應(yīng)用程序按Home鍵進(jìn)入后臺(tái)時(shí)的生命周期,以及從后臺(tái)回到前臺(tái)時(shí)的生命周期?
自己可以寫(xiě)個(gè)demo來(lái)測(cè)試一下
進(jìn)入后臺(tái)時(shí)
-(void)applicationWillResignActive:(UIApplication *)application;
-(void)applicationDidEnterBackground:(UIApplication *)application;
進(jìn)入前臺(tái)時(shí)
-(void)applicationDidEnterForeground:(UIApplication *)application;
-(void)applicationWillResignActive:(UIApplication *)application;
16、ViewController 的 alloc,loadView, viewDidLoad,viewWillAppear,viewDidUnload,dealloc、init分別是在什么時(shí)候調(diào)用的?在自定義ViewController的時(shí)候這幾個(gè)函數(shù)里面應(yīng)該做什么工作?
自己寫(xiě)代碼測(cè)試加深理解
alloc申請(qǐng)內(nèi)存時(shí)調(diào)用
loadView加載視圖時(shí)調(diào)用
ViewDidLoad視圖已經(jīng)加載后調(diào)用
ViewWillAppear視圖將要出現(xiàn)時(shí)調(diào)用
ViewDidUnload視圖已經(jīng)加載但沒(méi)有加載出來(lái)調(diào)用
dealloc銷(xiāo)毀該視圖時(shí)調(diào)用
init視圖初始化時(shí)調(diào)用
17、描述應(yīng)用程序的啟動(dòng)順序。
1. 程序入口main函數(shù)創(chuàng)建UIApplication實(shí)例和UIApplication代理實(shí)例。
2. 在UIApplication代理實(shí)例中重寫(xiě)啟動(dòng)方法,設(shè)置第一ViewController。
3. 在第一ViewController中添加控件,實(shí)現(xiàn)應(yīng)用程序界面。
18、為什么很多內(nèi)置類(lèi)如UITableViewControl的delegate屬性都是assign而不是retain?請(qǐng)舉例說(shuō)明。
防止循環(huán)引用
19、使用UITableView時(shí)候必須要實(shí)現(xiàn)的幾種方法?
-(NSInteger)tableView:(UITableView*)tableViewNumberOfRowsInSection:(NSInteger)section;?這個(gè)方法返回每個(gè)分段的行數(shù),不同分段返回不同的行數(shù)可以用switch來(lái)做,如果是單個(gè)列表就直接返回單個(gè)你想要的函數(shù)即可。?-(UITableViewCell*)tableView:(UITableView*)tableViewCellForRowAtIndexPath:(NSIndexPath)indexPath;?這個(gè)方法是返回我們調(diào)用的每一個(gè)單元格。通過(guò)我們索引的路徑的section和row來(lái)確定
20、寫(xiě)一個(gè)便利構(gòu)造器。
//id代表任意類(lèi)型指針,這里代表Student *,類(lèi)方法
+(id)studentWithName:(NSString *)newName andAge:(int)newAge?{? Student *stu=[[Student alloc]initName:newName andAge:newAge];? return [stu autorelease];//自動(dòng)釋放?}
21、UIImage初始化一張圖片有幾種方法?簡(jiǎn)述各自的優(yōu)缺點(diǎn)。
3種
imageNamed:系統(tǒng)會(huì)先檢查系統(tǒng)緩存中是否有該名字的Image,如果有的話,則直接返回,如果沒(méi)有,則先加載圖像到緩存,然后再返回。
initWithContentsOfFile:系統(tǒng)不會(huì)檢查系統(tǒng)緩存,而直接從文件系統(tǒng)中加載并返回。
imageWithCGImage:scale:orientation當(dāng)scale=1
查看更多關(guān)于“iOS培訓(xùn)資訊”的相關(guān)文章>>