我為什么要寫這篇文章
- 自己歸納總結(jié)禁舷,為校招做準備
- 方便自己隨時查閱,鞏固記憶
- 予人玫瑰手有余香
一毅往、簡述iOS中UIViewController的生命周期
先來看一張那個圖
一般一個UIViewController從被創(chuàng)建到顯示在屏幕上會經(jīng)歷如下過程
1牵咙、alloc 創(chuàng)建對象并在內(nèi)存中開辟一塊空間
2、init(initWithNibName) 初始化控制器對象并且初始化數(shù)據(jù)
3攀唯、loadView 如果view不存在則會調(diào)用此方法洁桌,在控制器沒有被銷毀前此方法可能會執(zhí)行多次
4、viewDidLoad 在loadView方法執(zhí)行完成view被創(chuàng)建成功后執(zhí)行此方法侯嘀,一般這個方法只執(zhí)行一次
5另凌、 viewWillAppare 視圖將要顯示在屏幕上的時候調(diào)用
6、 viewWillLayoutSubviews 視圖將要布局子控件時候調(diào)用
7戒幔、 viewDidLayoutSubviews 視圖剛剛布局好子控件時候調(diào)用
8吠谢、 viewDidAppear 視圖加載到窗口時調(diào)用
9、 viewWillDisappear 視圖即將消失溪食、被覆蓋或是隱藏時調(diào)用
10囊卜、viewDidDisappear 視圖已經(jīng)消失、被覆蓋或是隱藏時調(diào)用
- storyboard加載的是控制器及控制器view错沃,而xib加載的僅僅只是控制器的view
- 控制器view的生命周期:viewDidLoad -> viewWillAppear -> viewWillLayoutSubviews -> viewDidLayoutSubviews
-> viewDidAppear -> viewWillDisappear -> viewDidDisappear - 重寫loadView方法栅组,則會根據(jù)重寫的loadView方法創(chuàng)建view
- viewDidLoad被執(zhí)行多次的情況:A控制器push到B控制器,此時枢析,窗口顯示的是B控制器的view玉掸,如果收到內(nèi)存警告,一般會將A控制器中沒用的變量及view銷毀掉醒叁,之后當我們從B控制器pop到A控制器時司浪,就會再次執(zhí)行A控制器的loadView方法與viewDidLoad方法。
二把沼、什么是響應(yīng)者鏈啊易,它是怎么工作的
首先了解下響應(yīng)者對象這個概念:響應(yīng)者對象指的是有響應(yīng)和處理事件能力的對象。iOS中所有響應(yīng)者對象都繼承于UIResponder
所謂響應(yīng)者鏈就是講一系列響應(yīng)者鏈式地串聯(lián)起來饮睬,形成一條響應(yīng)鏈租谈,當某一對象不能處理事件時就將事件傳遞給下一個響應(yīng)者對象。我們來看一張圖
拓展:
- 響應(yīng)鏈通常是由一個個UIView組成的
- 一個視圖的下一個響應(yīng)者是它視圖控制器(UIViewController)(如果有的話)捆愁,然后再轉(zhuǎn)給它的父視圖(Super View)
- 視圖控制器(如果有的話)的下一個響應(yīng)者為其管理的視圖的父視圖
- UIWindow的下一個響應(yīng)者為UIApplication
- UIApplication是一條響應(yīng)鏈的終點
三割去、什么是序列化窟却,怎么將一個包含自定義對象的數(shù)組序列化到磁盤
所謂序列化就是將對象狀態(tài)轉(zhuǎn)換為可保持或者可傳輸格式的過程。在iOS中實現(xiàn)序列化只要實現(xiàn)NSCoding協(xié)議即可
我們先寫下如下代碼
#import "ViewController.h"
#import "Person.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
Person *person = [[Person alloc]init];
NSArray *array = @[person];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:array];
NSLog(@"%@---%@",array,data);
}
@end
這時我們command + R運行下你會看見如下錯誤:
這是因為我們沒有實現(xiàn)NSCoding協(xié)議方法呻逆,于是我們回到Person寫如下代碼:
#import "Person.h"
@interface Person()<NSCoding>
@end
@implementation Person
//序列化
- (instancetype)initWithCoder:(NSCoder *)aDecoder{
if (self = [super init]){
self = [aDecoder decodeObjectForKey:@"person"];
}
return self;
}
//反序列化
- (void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:self forKey:@"person"];
}
@end
ok夸赫,現(xiàn)在運行下
總結(jié):
- iOS中想要實現(xiàn)序列化和反序列化很簡單只要實現(xiàn)NSCoding協(xié)議中的initWithCoder和encodeWithCoder兩個方法就好了。
四咖城、你了解沙盒嗎茬腿,沙盒目錄結(jié)構(gòu)是怎樣的,什么是App Bundle酒繁,里面都有些什么
iOS沙盒可以簡單地理解成是一個目錄滓彰,而且我們修改這個目錄的時候?qū)Σ僮飨到y(tǒng)不會造成任何的損失,一個iOS APP的操作都是在自己的沙盒中進行的州袒。我們先來看一張圖
iOS沙盒結(jié)構(gòu):
- Application : 存放程序源文件揭绑,上架前經(jīng)過數(shù)字簽名,上架后不可修改
- Documents:常用目錄郎哭,iCloud備份目錄他匪,存放數(shù)據(jù),這里不能存緩存文件,否則上架不被通過
- Library :
- Caches:存放體積大又不需要備份的數(shù)據(jù)
- Preference:設(shè)置目錄,iCloud會備份設(shè)置信息
- tmp:存放臨時文件夸研,不會被備份邦蜜,而且這個文件下的數(shù)據(jù)有可能隨時被清除
App Bundle中存放: - info.plist :這個文件是很重要的一個文件,里面存放著iOS應(yīng)用程序的配置信息亥至,系統(tǒng)依賴此文件來獲取應(yīng)用程序的有關(guān)信息
- 可執(zhí)行文件:此文件包含應(yīng)用程序的入口和通過靜態(tài)連接到應(yīng)用程序target的代碼
- 資源文件 : 存放圖片悼沈、音、視頻文件
- 其他:可以嵌入定制的數(shù)據(jù)資源
五姐扮、在UIKit中絮供,frame與bounds的區(qū)別是什么
- frame相對于父視圖,是父視圖坐標系下的位置和大小。bounds相對于自身,是自身坐標系下的位置和大小茶敏。
- frame以父控件的左上角為坐標原點壤靶,bounds以自身的左上角為坐標原點
六、父類實現(xiàn)深拷貝時惊搏,子類如何實現(xiàn)深度拷貝贮乳。父類沒有實現(xiàn)深拷貝時,子類如何實現(xiàn)深度拷貝
- 深拷貝同淺拷貝的區(qū)別:淺拷貝是指針拷貝恬惯,對一個對象進行淺拷貝向拆,相當于對指向該對象的指針進行復(fù)制,產(chǎn)生一個新的指向這個對象的指針酪耳,那么就是有兩個指針指向同一個對象亲铡,這個對象銷毀后兩個指針都應(yīng)該置空。深拷貝是對一個對象進行拷貝,相當于對對象進行復(fù)制奖蔓,產(chǎn)生一個新的對象,那么就有兩個指針分別 指向兩個對象讹堤。當一個對象改變或者被銷毀后拷貝出來的新的對象不受影響吆鹤。
- 實現(xiàn)深拷貝需要實現(xiàn)NSCopying協(xié)議,實現(xiàn)- (id)copyWithZone:(NSZone *)zone 方法洲守。當對一個property屬性含有copy修飾符的時候疑务,在進行賦值操作的時候?qū)嶋H上就是調(diào)用這個方法。
- 父類實現(xiàn)深拷貝之后梗醇,子類只要重寫copyWithZone方法知允,在方法內(nèi)部調(diào)用父類的copyWithZone方法,之后再進行對自己屬性的處理叙谨。
- 父類沒有實現(xiàn)深拷貝温鸽,子類除了需要對自己的屬性進行處理,還要對父類的屬性進行處理手负。
我們來看以下代碼
#import "ViewController.h"
#import "Person.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
Person *person = [[Person alloc]init];
Person *aPerson = [person copy];
NSLog(@"%p---%p",person,aPerson);
}
@end
運行后發(fā)現(xiàn)崩了涤垫,錯誤信息是
意思是我們沒有實現(xiàn)NSCopying協(xié)議中copyWithZone的方法,回到Person文件
#import "Person.h"
@interface Person()<
NSCopying>
@end
@implementation Person
- (instancetype)copyWithZone:(NSZone *)zone{
return [[Person allocWithZone:zone]init];
}
@end
運行,ok成功了
拓展:
- 在NSString中使用copy和mutableCopy竟终、
NSString *str = @"string";
NSString *cpStr = [str copy];
NSMutableString *mucpStr = [str mutableCopy];
NSLog(@"str:%p-%@-cpStr:%p-%@-mucpStr%p-%@",str,str,cpStr,cpStr,mucpStr,mucpStr);
我們來看下打印輸出
str:0x10b7ba138-string-cpStr:0x10b7ba138-string-mucpStr0x608000250cb0-string
從打印的信息可以看出當調(diào)用copy復(fù)制時是淺拷貝蝠猬,調(diào)用mutableCopy復(fù)制時是深拷貝,若拷貝的對象是可變對象時均為深拷貝统捶,這里沒有列出
- 在定義屬性的時候copy和strong有什么區(qū)別
當你用copy修飾一個屬性時榆芦,默認會在它的setter方法中實現(xiàn)copy方法,而用strong修飾的屬性是不會在其setter方法中實現(xiàn)copy方法的喘鸟。
七匆绣、KVO,NSNotification迷守,delegate及block區(qū)別
首先什么是KVO:
所謂KVO即Key-Value-Observing犬绒,是cocoa框架實現(xiàn)的觀察者模式,一般會和KVC一塊使用兑凿,通過KVO可以監(jiān)測某一個值的變化凯力,比如一個UIView高度的變化,是一對多的關(guān)系礼华,一個值的變化會通知所有的觀察者
[self.tableView addObserver: self forKeyPath:@"contentOffSet" options: NSKeyValueObservingOptionNew context: nil];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
//做一些處理的操作
}
以上就給一個tableView添加了一個控制器作為它的觀察者咐鹤,當它有y軸上的偏移時,就會調(diào)用observeValueForKeyPath方法圣絮,更多關(guān)于[KVO]
(http://www.reibang.com/p/742b4b248da9)
NSNotification:
NSNotification是通知祈惶,也是一對多的使用場景隶垮。在某些情況下,KVO和NSNotification是一樣的民晒,都是狀態(tài)變化之后告知對方些己。NSNotification的特點,就是需要被觀察者先主動發(fā)出通知疹蛉,然后觀察者注冊監(jiān)聽后再來進行響應(yīng)活箕,比KVO多了發(fā)送通知的一步,但是其優(yōu)點是監(jiān)聽不局限于屬性的變化可款,還可以對多種多樣的狀態(tài)變化進行監(jiān)聽育韩,監(jiān)聽范圍廣,使用也更靈活闺鲸。
//發(fā)送通知
[[NSNotificationCenter defaultCenter]postNotificationName:@"notification" object:nil userInfo:@{@"key":@"value"}];
//添加通知
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(noted) name:@"notifiction" object:nil];
//注銷通知
[[NSNotificationCenter defaultCenter]removeObserver:self name:@"notification" object:nil];
delegate:
delegate 是代理筋讨,就是我不想做的事情交給別人做。比如狗需要吃飯摸恍,就通過delegate通知主人悉罕,主人就會給他做飯、盛飯误墓、倒水蛮粮,這些操作,這些狗都不需要關(guān)心谜慌,只需要調(diào)用delegate(代理人)就可以了然想,由其他類完成所需要的操作。所以delegate是一對一關(guān)系欣范。
block:
block是delegate的另一種形式变泄,是函數(shù)式編程的一種形式。使用場景跟delegate一樣恼琼,相比delegate更靈活妨蛹,而且代理的實現(xiàn)更直觀。
拓展:
- KVO一般的使用場景是數(shù)據(jù)晴竞,需求是數(shù)據(jù)變化蛙卤,一般使用KVO(觀察者模式)
- Notification 一般是進行全局通知,比如利好消息一出噩死,通知大家去買入颤难。Notification是弱關(guān)聯(lián),利好消息發(fā)出已维,你不需要知道是誰發(fā)的也可以做出相應(yīng)的反應(yīng)行嗤,同理發(fā)消息方也不需要知道接收方就可以正常發(fā)出消息。
- delegate一般的使用場景是行為垛耳,需求是需要別人幫我做一件事情栅屏,比如買賣股票飘千,我們一般使用delegate。
八栈雳、 怎么將一個函數(shù)放到主線程中執(zhí)行
//方法一:GCD方法护奈,通過向主線程隊列發(fā)送一個block塊,使block里的方法可以在主線程中執(zhí)行甫恩。
dispatch_async(dispatch_get_main_queue(), ^{
//需要執(zhí)行的方法
});
//方法二:NSOperationQueue
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue]; //主隊列
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
//需要執(zhí)行的方法
}];
[mainQueue addOperation:operation];
//方法三:NSThread
[self performSelector:@selector(method) onThread:[NSThread mainThread] withObject:nil waitUntilDone:YES models:nil];
[self performSelectorOnMainThread:@selector(method) withObject:nil waitUntilDone:YES];
[[NSThread mainThread] performSelector:@selector(method) withObject:nil];
//方法四:Runloop
[[NSRunLoop mainRunLoop] performSelector:@selector(method) withObject:nil];
九逆济、當定時器repeats屬性設(shè)為YES時,能在dealloc中調(diào)用invalid嗎磺箕,為什么
不能在dealloc中調(diào)用, 因為一旦設(shè)置repeats為yes抛虫,計時器會強持有self松靡,導(dǎo)致dealloc永遠不會被調(diào)用,這個類就永遠無法被釋放建椰。比如可以在viewDidDisappear中調(diào)用雕欺,這樣當類需要被回收的時候就可以正常執(zhí)行dealloc方法了。
拓展:
- 用scheduledTimerWithTimeInterval創(chuàng)建的NSTimer棉姐,在哪個線程創(chuàng)建就會被加入哪個線程的RunLoop中屠列,就運行在哪個線程。
- 自己創(chuàng)建的Timer伞矩,加入到哪個線程的RunLoop中就運行在哪個線程笛洛,需要手動加入線程。
十乃坤、線程是什么?進程又是什么?區(qū)別和聯(lián)系
這是問的操作系統(tǒng)相關(guān)的了苛让,是基礎(chǔ)
- 線程:線程是進程中一個獨立執(zhí)行的控制單元(路徑),一個進程至少包含一條線程,即主線程
- 進程:正在運行的程序,負責程序的內(nèi)存分配,一個程序至少要有一個進程
- 進程和線程都是一個時間段的描述湿诊,是CPU工作時間段的描述狱杰,進程是cpu資源分配的最小單位,線程是cpu調(diào)度的最小單位厅须。
==============================================================
未完待續(xù)仿畸。。朗和。
先總結(jié)十條吧错沽,希望對您面試有幫助,如有什么錯誤歡迎指正