1.請描述copy,retain,assign,weak的作用
copy: 表示賦值特性,setter方法將傳入對象復(fù)制一份;需要完全一份新的變量時(shí)箩兽。
retain: 表示持有特性,setter方法將傳入?yún)?shù)先保留章喉,再賦值汗贫,傳入?yún)?shù)的retaincount會+1;
assign: 是賦值特性,setter方法將傳入?yún)?shù)賦值給實(shí)例變量;僅設(shè)置變量時(shí);
weak:弱應(yīng)用秸脱,但最后一個(gè)strong型指針不再指向?qū)ο舐浒敲磳ο缶蜁会尫牛瑫r(shí)所有的weak型指針都將會被清除
2.frame跟bounds有什么區(qū)別撞反,蘋果為什么要這么設(shè)計(jì)妥色?
frame指的是:該view在父view坐標(biāo)系統(tǒng)中的位置和大小。(參照點(diǎn)是父親的坐標(biāo)系統(tǒng))
bounds指的是:該view在本身坐標(biāo)系統(tǒng)中 的位置和大小遏片。(參照點(diǎn)是本身坐標(biāo)系統(tǒng))
3.但處理屬性聲明的時(shí)候嘹害,原子(atomic)跟非原子(non-atomic)屬性有什么區(qū)別?
1). atomic提供多線程安全吮便。是防止在寫未完成的時(shí)候被另外一個(gè)線程讀取笔呀,造成數(shù)據(jù)錯(cuò)誤
2). non-atomic:在自己管理內(nèi)存的環(huán)境中,解析的訪問器保留并自動釋放返回的值髓需,
如果指定了 nonatomic 许师,那么訪問器只是簡單地返回這個(gè)值。
4.block有幾種類型,分別描述他們在內(nèi)存中的位置微渠?
3種
_NSConcreteGlobalBlock 全局靜態(tài)
_NSConcreteStackBlock 保存在棧中搭幻,出函數(shù)作用域就銷毀
_NSConcreteMallocBlock 保存在堆中,retainCount == 0銷毀
5.盡可能詳細(xì)的描述響應(yīng)鏈條
如果view的控制器存在逞盆,就傳遞給控制器檀蹋;如果控制器不存在,則將其傳遞給它的父視圖,在視圖層次結(jié)構(gòu)的最頂級視圖云芦,
如果也不能處理收到的事件或消息俯逾,則其將事件或消息傳遞給window對象進(jìn)行處理,如果window對象也不處理,
則其將事件或消息傳遞給UIApplication對象,如果UIApplication也不能處理該事件或消息舅逸,則將其丟棄
First Responser -- > The Window -- >TheApplication -- > App Delegate
6.淺拷貝跟深拷貝的區(qū)別桌肴?
淺拷貝(影子克隆):只復(fù)制對象的基本類型,對象類型,仍屬于原來的引用.
深拷貝(深度克隆):不緊復(fù)制對象的基本類,同時(shí)也復(fù)制原對象中的對象.就是說完全是新對象產(chǎn)生的.
淺拷貝和深拷貝之間的區(qū)別:淺拷貝是指將對象中的數(shù)值類型的字段拷貝到新的對象中,而對象中的引用型字段則指復(fù)制它的一個(gè)引用到目標(biāo)對象琉历。
如果改變目標(biāo)對象 中引用型字段的值他將反映在原是對象中坠七,也就是說原始對象中對應(yīng)的字段也會發(fā)生變化。
深拷貝與淺拷貝不同的是對于引用的處理善已,深拷貝將會在新對象中創(chuàng)建一 個(gè)新的和原是對象中對應(yīng)字段相同(內(nèi)容相同)的字段灼捂,
也就是說這個(gè)引用和原是對象的引用是不同的,我們在改變新對象中的這個(gè)字段的時(shí)候是不會影響到原始對 象中對應(yīng)字段的內(nèi)容换团。所以對于原型模式也有不同的兩種處理方法:
對象的淺拷貝和深拷貝
7._block的作用是什么悉稠?_weak的作用是什么?他們對于內(nèi)存的影響是怎樣的艘包?
block下循環(huán)引用的問題:
__block本身并不能避免循環(huán)引用的猛,避免循環(huán)引用需要在block內(nèi)部把__block修飾的obj置為nil
__weak可以避免循環(huán)引用,但是其會導(dǎo)致外部對象釋放了之后想虎,block 內(nèi)部也訪問不到這個(gè)對象的問題卦尊,
我們可以通過在 block 內(nèi)部聲明一個(gè) __strong
的變量來指向 weakObj,使外部對象既能在 block 內(nèi)部保持住舌厨,又能避免循環(huán)引用的問題
__block與__weak功能上的區(qū)別:
__block會持有該對象岂却,即使超出了該對象的作用域,該對象還是會存在的裙椭,直到block對象從堆上銷毀躏哩;
而__weak僅僅是將該對象賦值給weak對象,當(dāng)該對象銷毀時(shí)揉燃,weak對象將指向nil扫尺;
__block可以讓block修改局部變量,而__weak不能炊汤。
另外正驻,MRC中__block是不會引起retain弊攘;但在ARC中__block則會引起retain。所以ARC中應(yīng)該使用__weak姑曙。
8.線程和進(jìn)程的區(qū)別
(1)一個(gè)線程只能屬于一個(gè)進(jìn)程襟交,而一個(gè)進(jìn)程可以有多個(gè)線程,但至少有一個(gè)線程伤靠。線程是[操作系統(tǒng)](http://lib.csdn.net/base/operatingsystem)
可識別的最小執(zhí)行和調(diào)度單位婿着。
(2)資源分配給進(jìn)程,同一進(jìn)程的所有線程共享該進(jìn)程的所有資源醋界。 同一進(jìn)程中的多個(gè)線程共享代碼段(代碼和常量),數(shù)據(jù)段(全局變量和靜態(tài)變量)提完,擴(kuò)展段(堆存儲)形纺。
但是每個(gè)線程擁有自己的棧段,棧段又叫運(yùn)行時(shí)段徒欣,用來存放所有局部變量和臨時(shí)變量逐样。
(3)處理機(jī)分給線程,即真正在處理機(jī)上運(yùn)行的是線程打肝。
(4)線程在執(zhí)行過程中脂新,需要協(xié)作同步。不同進(jìn)程的線程間要利用消息通信的辦法實(shí)現(xiàn)同步粗梭。
進(jìn)程和線程并不是一一對應(yīng)的争便,一個(gè)程序執(zhí)行在不同的數(shù)據(jù)集上就成為不同的進(jìn)程,
可以用進(jìn)程控制塊來唯一地標(biāo)識每個(gè)進(jìn)程断医。而這一點(diǎn)正是程序無法做到的滞乙,由于程序沒有和數(shù)據(jù)產(chǎn)生直接的聯(lián)系,即使是執(zhí)行不同的數(shù)據(jù)的程序鉴嗤,
他們的指令的集合依然是一樣的斩启,所以無法唯一地標(biāo)識出這些運(yùn)行于不同數(shù)據(jù)集上的程序。一般來說醉锅,一個(gè)進(jìn)程肯定有一個(gè)與之對應(yīng)的程序兔簇,而且只有一個(gè)。
而一個(gè)程序有可能沒有與之對應(yīng)的進(jìn)程(因?yàn)樗鼪]有執(zhí)行)硬耍,也有可能有多個(gè)進(jìn)程與之對應(yīng)(運(yùn)行在幾個(gè)不同的數(shù)據(jù)集上)
9.描述線程垄琐,runloop的關(guān)系
RunLoop 的作用就是來管理線程的,當(dāng)線程的 RunLoop,開啟后默垄,線程就會在執(zhí)行完任務(wù)后此虑,處于休眠狀態(tài),隨時(shí)等待接受新的任務(wù)口锭,而不是退出朦前。
只有主線程的RunLoop是默認(rèn)開啟的介杆,所以程序在開啟后,會一直運(yùn)行韭寸,不會退出春哨。其他線程的RunLoop
如果需要開啟,就手動開啟恩伺。
10.描述自動釋放池在什么時(shí)候釋放赴背?
自動釋放池以棧的形式實(shí)現(xiàn):當(dāng)你創(chuàng)建一個(gè)新的自動釋放池時(shí),它將被添加到
棧頂.當(dāng)一個(gè)對象收到autorelease消息的時(shí)候,它被添加到當(dāng)前線程的處于
棧頂?shù)牡淖詣俞尫懦刂?當(dāng)自動釋放池被回收時(shí),他們就從棧中被刪除,并且會
給池子里面的所有對象都會做一次release操作
11.導(dǎo)致界面卡頓的原因,可以從CPU晶渠,GPU兩方面回答凰荚?
CPU
一:對象操作
1)對象創(chuàng)建
2)對象調(diào)整
3)對象銷毀
二:排版
1)布局計(jì)算
2)Autolayout
3)文本計(jì)算
4)太多的layer或者幾何圖形
三:繪制
1)文本繪制
2)圖片的解碼
3)圖像的繪制
GPU
一:接收提交的紋理(Texture)和頂點(diǎn)描述(三角形)
二:應(yīng)用變化(transform)、混合并渲染
1)紋理的渲染
2)視圖的混合
3)圖形的生成
三:輸出到屏幕
12.執(zhí)行如下的代碼會發(fā)生什么情況褒脯?為什么便瑟?
Ball *ball = [[[Ball alloc]init]autorelease]autorelease];
會崩潰
對象執(zhí)行兩次autorelease意味著自動釋放池銷毀的時(shí)候 對象會執(zhí)行兩次release操作 會報(bào)野指針錯(cuò)誤
13.我們說的objc是動態(tài)運(yùn)行時(shí)語言是什么意思?盡可能多的描述你所知道的以及運(yùn)行時(shí)在項(xiàng)目中的應(yīng)用場景番川。
動態(tài):
主要是將數(shù)據(jù)類型的確定由編譯時(shí)到涂,推遲到了運(yùn)行時(shí)。
這個(gè)問題其實(shí)淺涉及到兩個(gè)概念颁督,運(yùn)行時(shí)和多態(tài)践啄。 簡單來說,運(yùn)行時(shí)機(jī)制使我們直到運(yùn)行時(shí)才去決定一個(gè)對象的類別沉御,以及調(diào)用該類別對象指定方法屿讽。
OC的動態(tài)特性表現(xiàn)為了三個(gè)方面:動態(tài)類型、動態(tài)綁定吠裆、動態(tài)加載聂儒。之所以叫做動態(tài),是因?yàn)楸仨毜竭\(yùn)行時(shí)(run time)才會做一些事情硫痰。
(1)動態(tài)類型
動態(tài)類型衩婚,說簡單點(diǎn)就是id類型。動態(tài)類型是跟靜態(tài)類型相對的效斑。像內(nèi)置的明確的基本類型都屬于靜態(tài)類型(int非春、NSString等)。
靜態(tài)類型在 編譯的時(shí)候就能被識別出來缓屠。所以奇昙,若程序發(fā)生了類型不對應(yīng),編譯器就會發(fā)出警告敌完。
而動態(tài)類型就編譯器編譯的時(shí)候是不能被識別的储耐,要等到運(yùn)行時(shí)(run time),即程序運(yùn)行的時(shí)候才會根據(jù)語境來識別滨溉。所以這里面就有兩個(gè)概念要分清:編譯時(shí)跟運(yùn)行時(shí)什湘。
id obj = someInstance;
if ([obj isKindOfClass:someClass]) {
someClass *classSpecifiedInstance = (someClass *)obj;
}
(2)動態(tài)綁定
動態(tài)綁定(dynamic binding)貌似比較難記憶长赞,但事實(shí)上很簡單,只需記住關(guān)鍵詞@selector/SEL即可闽撤。
先來看看“函數(shù)”得哆,對于其他一些靜態(tài)語言,比如 c++,一般在編譯的時(shí)候就已經(jīng)將將要調(diào)用的函數(shù)的函數(shù)簽名都告訴編譯器了哟旗。
靜態(tài)的贩据,不能改變。而在OC中闸餐,其實(shí)是沒有函數(shù)的概念的饱亮,我們叫“消息機(jī) 制”,所謂的函數(shù)調(diào)用就是給對象發(fā)送一條消息舍沙。
這時(shí)近尚,動態(tài)綁定的特性就來了。OC可以先跳過編譯场勤,到運(yùn)行的時(shí)候才動態(tài)地添加函數(shù)調(diào)用,在運(yùn)行時(shí)才決定要調(diào) 用什么方法歼跟,需要傳什么參數(shù)進(jìn)去。
這就是動態(tài)綁定,要實(shí)現(xiàn)他就必須用SEL變量綁定一個(gè)方法傍妒。最終形成的這個(gè)SEL變量就代表一個(gè)方法的引用悯嗓。
這里要注意 一點(diǎn):SEL并不是C里面的函數(shù)指針,雖然很像骚秦,但真心不是函數(shù)指針她倘。SEL變量只是一個(gè)整數(shù),他是該方法的ID作箍,@selector()就是取類方法的編號硬梁。
以前的函數(shù)調(diào)用,是根據(jù)函數(shù)名胞得,也就是 字符串去查找函數(shù)體荧止。但現(xiàn)在,我們是根據(jù)一個(gè)ID整數(shù)來查找方法阶剑,整數(shù)的查找字自然要比字符串的查找快得多跃巡!
所以,動態(tài)綁定的特定不僅方便牧愁,而且效率更 高素邪。
由于OC的動態(tài)特性,在OC中其實(shí)很少提及“函數(shù)”的概念猪半,傳統(tǒng)的函數(shù)一般在編譯時(shí)就已經(jīng)把參數(shù)信息和函數(shù)實(shí)現(xiàn)打包到編譯后的源碼中了兔朦,而在OC中最常使 用的是消息機(jī)制偷线。
調(diào)用一個(gè)實(shí)例的方法,所做的是向該實(shí)例的指針發(fā)送消息烘绽,實(shí)例在收到消息后淋昭,從自身的實(shí)現(xiàn)中尋找響應(yīng)這條消息的方法
(3)動態(tài)加載
根據(jù)需求加載所需要的資源,這點(diǎn)很容易理解安接,對于iOS開發(fā)來說翔忽,基本就是根據(jù)不同的機(jī)型做適配。最經(jīng)典的例子就是在Retina設(shè)備上加載@2x的圖片盏檐,而在老一些的普通屏設(shè)備上加載原圖歇式。
14.數(shù)組和鏈表的區(qū)別
(http://www.cnblogs.com/FCWORLD/archive/2010/11/20/1882391.html)
數(shù)組是將元素在內(nèi)存中連續(xù)存放,由于每個(gè)元素占用內(nèi)存相同胡野,可以通過下標(biāo)迅速訪問數(shù)組中任何元素材失。
但是如果要在數(shù)組中增加一個(gè)元素,需要移動大量元素硫豆,在內(nèi)存中空出一個(gè)元素的空間龙巨,然后將要增加的元素放在其中。
同樣的道理熊响,如果想刪除一個(gè)元素旨别,同樣需要移動大量元素去填掉被移動的元素。
如果應(yīng)用需要快速訪問數(shù)據(jù)汗茄,很少或不插入和刪除元素秸弛,就應(yīng)該用數(shù)組。
鏈表恰好相反洪碳,鏈表中的元素在內(nèi)存中不是順序存儲的递览,而是通過存在元素中的指針聯(lián)系到一起。
比如:上一個(gè)元素有個(gè)指針指到下一個(gè)元素瞳腌,以此類推绞铃,直到最后一個(gè)元素。如果要訪問鏈表中一個(gè)元素嫂侍,需要從第一個(gè)元素開始憎兽,一直找到需要的元素位置。
但是增加和刪除一個(gè)元素對于鏈表數(shù)據(jù)結(jié)構(gòu)就非常簡單了吵冒,只要修改元素中的指針就可以了纯命。
如果應(yīng)用需要經(jīng)常插入和刪除元素你就需要用鏈表數(shù)據(jù)結(jié)構(gòu)了。
C++語言中可以用數(shù)組處理一組數(shù)據(jù)類型相同的數(shù)據(jù)痹栖,但不允許動態(tài)定義數(shù)組的大小亿汞,即在使用數(shù)組之前必須確定數(shù)組的大小。
而在實(shí)際應(yīng)用中揪阿,用戶使用數(shù)組之前有時(shí)無法準(zhǔn)確確定數(shù)組的大小疗我,
只能將數(shù)組定義成足夠大小咆畏,這樣數(shù)組中有些空間可能不被使用,從而造成內(nèi)存空間的浪費(fèi)吴裤。****鏈表是一種常見的數(shù)據(jù)組織形式旧找,它采用動態(tài)分配內(nèi)存的形式實(shí)現(xiàn)。
需要時(shí)可以用new分配內(nèi)存空間麦牺,不需要時(shí)用delete將已分配的空間釋放钮蛛,不會造成內(nèi)存空間的浪費(fèi)。
(1) 從邏輯結(jié)構(gòu)角度來看
a, 數(shù)組必須事先定義固定的長度(元素個(gè)數(shù))剖膳,不能適應(yīng)數(shù)據(jù)動態(tài)地增減的情況魏颓。當(dāng)數(shù)據(jù)增加時(shí),可能超出原先定義的元素個(gè)數(shù)吱晒;當(dāng)數(shù)據(jù)減少時(shí)甸饱,造成內(nèi)存浪費(fèi)÷乇簦
b,鏈表動態(tài)地進(jìn)行存儲分配叹话,可以適應(yīng)數(shù)據(jù)動態(tài)地增減的情況,且可以方便地插入墩瞳、刪除數(shù)據(jù)項(xiàng)驼壶。
(數(shù)組中插入、刪除數(shù)據(jù)項(xiàng)時(shí)矗烛,需要移動其它數(shù)據(jù)項(xiàng))
(2)從內(nèi)存存儲角度來看
a,(靜態(tài))數(shù)組從棧中分配空間, 對于程序員方便快速,但自由度小÷崂#
b, 鏈表從堆中分配空間, 自由度大但申請管理比較麻煩.
15.KVC 跟KVO有啥聯(lián)系
KVC
KVC : 鍵值編碼瞭吃,是Key Value Coding 的簡稱,cocoa的標(biāo)準(zhǔn)組成部分涣旨,是一種可以直接通過字符串的名字(Key)來訪問類屬性的機(jī)制歪架,
而不是通過調(diào)用Setter方法、Getter方法進(jìn)行訪問霹陡。
KVC是一個(gè)用于間接訪問對象屬性的機(jī)制(只是通過字符串訪問和蚪,而不是訪問器方法去訪問一個(gè)對象實(shí)例變量的機(jī)制),
使用該機(jī)制不需要調(diào)用set或get方法和“->”方法訪問成員變量烹棉,而是通過setValue:forKey: 和 valueForKey:方法進(jìn)行成員變量的訪問攒霹,
將在內(nèi)部查找名為_key或key的成員變量,如果找不到浆洗,就會報(bào)錯(cuò)催束。
KVC的使用環(huán)境:無論是property還是普通的全局屬性變量,都可以使用KVC伏社;
KVC優(yōu)點(diǎn):1.主要的好處就是減少代碼量抠刺;2.沒有property的變量(即:私有變量private)也能通過KVC進(jìn)行設(shè)置塔淤。
KVC缺點(diǎn):如果key只寫錯(cuò),編寫的時(shí)候不會報(bào)錯(cuò)速妖,但是運(yùn)行的時(shí)候會報(bào)錯(cuò)高蜂;
KVO
KVO : 鍵值監(jiān)聽,是Key Value ObserVing 的簡稱罕容,當(dāng)指定對象的屬性被修改之后备恤,允許對象接收到通知的機(jī)制。
KVO:是一個(gè)對象能夠觀察另外一個(gè)對象的屬性的值杀赢,并且能夠發(fā)現(xiàn)值得變化烘跺。
KVO適合一個(gè)任意類型的對象對另外的對象進(jìn)行監(jiān)聽,當(dāng)被監(jiān)聽的對象一旦發(fā)生改變脂崔,觀察者馬上做出反應(yīng)滤淳。
但是也只能對屬性作出反應(yīng),而不會對方法或動作作出反應(yīng)砌左。
KVO優(yōu)點(diǎn):1.能夠提供一種簡單的方法實(shí)現(xiàn)兩個(gè)對象的同步脖咐;
2、能夠?qū)?nèi)部對象的狀態(tài)改變作出響應(yīng)汇歹,而且不需要改變內(nèi)部對象的實(shí)現(xiàn)屁擅;
3.能夠提供被觀察者屬性的最新值和之前的值;
4.使用key Path來觀察屬性产弹,因此可以觀察嵌套對象派歌;
5.完成了對觀察對象的抽象,因?yàn)椴恍枰~外的代碼來允許觀察者被觀察痰哨。
KVO缺點(diǎn):
1.我們觀察的屬性必須使用strings定義胶果,編譯時(shí)不會出現(xiàn)警告;
2.對屬性重構(gòu)斤斧,將導(dǎo)致觀察代碼不可用早抠;
3.復(fù)雜的 if 語句要求對象正在觀察多個(gè)值,是因?yàn)樗械挠^察代碼通過一個(gè)方法來指向撬讽;
4.當(dāng)釋放觀察者的時(shí)候不需要移除觀察者蕊连。
總結(jié)一下
1.KVO KVC 沒聯(lián)系
2.KVO 是監(jiān)聽屬性值的改變
3.KVO 底層實(shí)現(xiàn)原理是系統(tǒng)給當(dāng)前類創(chuàng)建子類 , 在子類 setter 方法調(diào)用父類的 setter 方法
16.消息轉(zhuǎn)發(fā)機(jī)制,消息發(fā)送為什么會失斢沃纭甘苍?
重定向
在消息轉(zhuǎn)發(fā)機(jī)制執(zhí)行前,Runtime 系統(tǒng)會再給我們一次偷梁換柱的機(jī)會烘豌,即通過重載- (id)forwardingTargetForSelector:(SEL)aSelector
方法替換消息的接受者為其他對象:
1234567
- (id)forwardingTargetForSelector:(SEL)aSelector{ if(aSelector == @selector(mysteriousMethod:)){ return alternateObject; } return [super forwardingTargetForSelector:aSelector];}
畢竟消息轉(zhuǎn)發(fā)要耗費(fèi)更多時(shí)間羊赵,抓住這次機(jī)會將消息重定向給別人是個(gè)不錯(cuò)的選擇,~~不過千萬別返回self
,因?yàn)槟菢訒姥h(huán)昧捷。~~ 如果此方法返回nil或self,則會進(jìn)入消息轉(zhuǎn)發(fā)機(jī)制(forwardInvocation:
);否則將向返回的對象重新發(fā)送消息闲昭。
[](http://yulingtianxia.com/blog/2014/11/05/objective-c-runtime/#轉(zhuǎn)發(fā))轉(zhuǎn)發(fā)
當(dāng)動態(tài)方法解析不作處理返回NO
時(shí),消息轉(zhuǎn)發(fā)機(jī)制會被觸發(fā)靡挥。在這時(shí)forwardInvocation:
方法會被執(zhí)行序矩,我們可以重寫這個(gè)方法來定義我們的轉(zhuǎn)發(fā)邏輯:
12345678
- (void)forwardInvocation:(NSInvocation *)anInvocation{ if ([someOtherObject respondsToSelector: [anInvocation selector]]) [anInvocation invokeWithTarget:someOtherObject]; else [super forwardInvocation:anInvocation];}
該消息的唯一參數(shù)是個(gè)NSInvocation
類型的對象——該對象封裝了原始的消息和消息的參數(shù)。我們可以實(shí)現(xiàn)forwardInvocation:
方法來對不能處理的消息做一些默認(rèn)的處理跋破,也可以將消息轉(zhuǎn)發(fā)給其他對象來處理簸淀,而不拋出錯(cuò)誤。
這里需要注意的是參數(shù)anInvocation
是從哪的來的呢毒返?其實(shí)在forwardInvocation:
消息發(fā)送前租幕,Runtime系統(tǒng)會向?qū)ο蟀l(fā)送methodSignatureForSelector:
消息,并取到返回的方法簽名用于生成NSInvocation
對象拧簸。所以我們在重寫forwardInvocation:
的同時(shí)也要重寫methodSignatureForSelector:
方法劲绪,否則會拋異常。
當(dāng)一個(gè)對象由于沒有相應(yīng)的方法實(shí)現(xiàn)而無法響應(yīng)某消息時(shí)盆赤,運(yùn)行時(shí)系統(tǒng)將通過forwardInvocation:
消息通知該對象贾富。每個(gè)對象都從NSObject
類中繼承了forwardInvocation:
方法。然而牺六,NSObject
中的方法實(shí)現(xiàn)只是簡單地調(diào)用了doesNotRecognizeSelector:
颤枪。通過實(shí)現(xiàn)我們自己的forwardInvocation:
方法,我們可以在該方法實(shí)現(xiàn)中將消息轉(zhuǎn)發(fā)給其它對象淑际。
forwardInvocation:
方法就像一個(gè)不能識別的消息的分發(fā)中心畏纲,將這些消息轉(zhuǎn)發(fā)給不同接收對象〈郝疲或者它也可以象一個(gè)運(yùn)輸站將所有的消息都發(fā)送給同一個(gè)接收對象盗胀。
它可以將一個(gè)消息翻譯成另外一個(gè)消息,或者簡單的”吃掉“某些消息淡溯,因此沒有響應(yīng)也沒有錯(cuò)誤读整。forwardInvocation:
方法也可以對不同的消息提供同樣的響應(yīng)簿训,
這一切都取決于方法的具體實(shí)現(xiàn)咱娶。該方法所提供是將不同的對象鏈接到消息鏈的能力。
注意: forwardInvocation:
方法只有在消息接收對象中無法正常響應(yīng)消息時(shí)才會被調(diào)用强品。 所以膘侮,如果我們希望一個(gè)對象將negotiate
消息轉(zhuǎn)發(fā)給其它對象,則這個(gè)對象不能有negotiate
方法的榛。否則琼了,forwardInvocation:
將不可能會被調(diào)用。
消息發(fā)送和轉(zhuǎn)發(fā)流程可以概括為:消息發(fā)送(Messaging)是 Runtime 通過 selector 快速查找 IMP 的過程,
有了函數(shù)指針就可以執(zhí)行對應(yīng)的方法實(shí)現(xiàn)雕薪;消息轉(zhuǎn)發(fā)(Message Forwarding)
是在查找 IMP 失敗后執(zhí)行一系列轉(zhuǎn)發(fā)流程的慢速通道昧诱,如果不作轉(zhuǎn)發(fā)處理,則會打日志和拋出異常所袁。
17.使用NStimer要注意什么盏档?
存在延遲
不管是一次性的還是周期性的timer的實(shí)際觸發(fā)事件的時(shí)間,都會與所加入的RunLoop和RunLoop Mode有關(guān)燥爷,
如果此RunLoop正在執(zhí)行一個(gè)連續(xù)性的運(yùn)算蜈亩,timer就會被延時(shí)出發(fā)。重復(fù)性的timer遇到這種情況前翎,
如果延遲超過了一個(gè)周期稚配,則會在延時(shí)結(jié)束后立刻執(zhí)行,并按照之前指定的周期繼續(xù)執(zhí)行
同一個(gè)timer在重復(fù)使用之前必需invalidate
同一個(gè)timer在重復(fù)使用之前必需invalidate, 否則會造成之前的timer無法停掉港华,兩個(gè)timer同時(shí)存在道川。導(dǎo)致的現(xiàn)象就是timer同時(shí)更新兩次。
不要在dealloc函數(shù)中停止并釋放NSTimer
如果這樣做苹丸,會導(dǎo)致對象永遠(yuǎn)無法調(diào)用dealloc函數(shù)愤惰,也就是會造成內(nèi)存泄漏。一個(gè)比較合理的解釋是NSTimer的回調(diào)方法具有retain屬性赘理,所以不停止它的情況下被引用對象的retainCount無法降為0宦言,導(dǎo)致內(nèi)存泄漏的死循環(huán)。
不用scheduled方式初始化的商模,需要將timer添加到runloop中
NSTimer *myTimer = [NSTimer timerWithTimeInterval:3.0 target:self selector:@selector(timerFired:) userInfo:nilrepeats:NO];
[[NSRunLoopcurrentRunLoop] addTimer:myTimer forMode:NSDefaultRunLoopMode];
滑動UIScrollView的時(shí)候
當(dāng)RunLoop處于UITrackingRunLoopMode模式的時(shí)候(滑動UIScrollView的時(shí)候)奠旺,使用
scheduledTimerWithTimeInterval:(NSTimeInterval)seconds
invocation:(NSInvocation *)invocation
repeats:(BOOL)repeats
的類方法創(chuàng)建的Timer,是不會收到響應(yīng)事件施流。只有RunLoop切換到Default模式時(shí)才可以正常響應(yīng)响疚。如果希望滑動時(shí)也可以響應(yīng)Timer時(shí)間,需要把Timer加到RunLoop并指定模式為NSRunLoopCommonModes瞪醋。
18.獲取Wi-Fi信息的框架是什么忿晕?
SystemConfiguration.famework
附上框架總覽:http://blog.csdn.net/hdfqq188816190/article/details/50725314
19.應(yīng)用程序的生命周期:appdelegate每個(gè)方法的介紹
一。appdelegate每個(gè)方法的簡單介紹:
1银受、應(yīng)用程序啟動践盼,并進(jìn)行初始化時(shí)候調(diào)用該方法:aaaplication:didFimnishLanuchingWithOptions:
2、應(yīng)用進(jìn)入前臺并處于活動狀態(tài)時(shí)候調(diào)用:applicationDidBecomeActive:
3宾巍、應(yīng)用從活動狀態(tài)進(jìn)入到非活動狀態(tài):applicationWillResignActive :
4咕幻、應(yīng)用進(jìn)入到后臺時(shí)候調(diào)用的方法:applicationDidEnterBackground:
5、應(yīng)用進(jìn)入到前臺時(shí)候調(diào)用的方法:appplicationWillEnterForeground:
6顶霞、applicationWillTeminate:應(yīng)用被終止的狀態(tài):
總結(jié):
1.從這個(gè)過程我們就知道肄程,appdelegate的每個(gè)方法會對應(yīng)一個(gè)通知,沒當(dāng)調(diào)用那個(gè)方法的時(shí)候,就會發(fā)出那個(gè)方法對應(yīng)的通知蓝厌;
2.下面的幾個(gè)場景玄叠,我就不一一說明,直接貼圖了拓提;
3.再貼圖之前诸典,先把a(bǔ)ppdelegate每個(gè)方法對應(yīng)的通知都貼出來;
方法 本地通知
didFimnishLanuchingWithOptions: UIApplicationDidFinishLaunchingNotification
applicationDidBecomeActive UIApplicationDidBecomeActiveNOtification
applicationWillResignActive UIApplicationWillResignActiveNotification
applicationDidEnterBackground UIApplicationDidEnterBackgroundNotification
appplicationWillEnterForeground UIApplicationwillEnterForegroundNotification
applicationWillTeminate UIApplicationWillTeminateNotification