1、內(nèi)存管理:
__weak?只是把只地址取得 放到以變量為key的哈希表里面 進行若引用的存儲突倍,對原有對象是沒有影響的 潦俺,
2沃于、循環(huán)引用
一般arc下胰坟,直接__weak可以阻斷循環(huán)引用稿壁,在mrc下__block阻斷循環(huán)引用的發(fā)生 原因是__block在arc下是不增加引用計數(shù)的 所以可以達到這一目的辩尊,在arc下如果也要使用__block達到這個效果 需要在block體里面進行制空赎婚,釋放強引用只锻,這樣才可以做到解除循環(huán)引用玖像。關(guān)于制空為什么會解除強引用 ,是因為在arc下__strong變量齐饮,當(dāng)沒有任何人持有的時候御铃,這時候會被廢棄。
3沈矿、GCD ?:dispatch_sync或者dispatch_async?只是對于處理的結(jié)果是否保持同步或者異步上真,sync是要等待處理結(jié)果的,async不需要等待;serial queue只是說明當(dāng)前隊列是串行執(zhí)行羹膳,concurrent queue是系統(tǒng)幫助管理多線程的處理操作睡互,并不見得是由一個線程來處理。所以總結(jié)一下陵像,一個是面向結(jié)果是否等待就珠,一個是面向如何處理任務(wù)。
4醒颖、坐標(biāo)系轉(zhuǎn)換樣例
//?controllerA?中有一個UITableView,?UITableView里有多行UITableVieCell妻怎,cell上放有一個button//?在controllerA中實現(xiàn):receiver 也就是調(diào)用者是將要轉(zhuǎn)換的view的父視圖。CGRect?rc?=?[cell?convertRect:cell.btn.frame?toView:self.view];或CGRect?rc?=?[self.view?convertRect:cell.btn.frame?fromView:cell];
5泞歉、動態(tài)方法解析與消息轉(zhuǎn)發(fā):如果以上的類中沒有找到對應(yīng)的selector(一般保險起見先用respondsToSelector:內(nèi)省判斷):逼侦,還可以利用消息轉(zhuǎn)發(fā)機制依次執(zhí)行以下流程: ? ??Method Resolution(動態(tài)方法解析):用所屬類的類方法+(BOOL)resolveInstanceMethod:(實例方法)或者+(BOOL)resolveClassMethod:(類方法),在此方法里添加class_addMethod函數(shù)。一般用于@dynamic動態(tài)屬性腰耙。(當(dāng)一個屬性聲明為@dynamic榛丢,就是向編譯器保證編譯時不用管/get實現(xiàn),一定會在運行時實現(xiàn))挺庞。
Fast Forwarding?(快速消息轉(zhuǎn)發(fā)):如果上一步無法響應(yīng)消息晰赞,調(diào)用- (id)forwardingTargetForSelector:(SEL)aSelector方法,將消息接受者轉(zhuǎn)發(fā)到另一個對象target(不能為self,否則死循環(huán))掖鱼。
Normal Forwarding(普通消息轉(zhuǎn)發(fā)):如果上一步無法響應(yīng)消息:調(diào)用方法簽名- (NSMethodSignature?)methodSignatureForSelector:(SEL)aSelector然走,方法簽名目的將函數(shù)的參數(shù)類型和返回值封裝;如果返回非nil戏挡,則創(chuàng)建一個NSInvocation對象利用方法簽名和selector封裝未被處理的消息丰刊,作為參數(shù)傳遞給- (void)forwardInvocation:(NSInvocation)anInvocation。這一步比較耗時增拥。
簡單的說消息轉(zhuǎn)發(fā)啄巧,就是3種,1添加一個方法掌栅。2讓某個對象去接消息秩仆。3創(chuàng)造一個方法簽名,然后讓其他對象去接猾封。
Fast Forwarding?(快速消息轉(zhuǎn)發(fā)):如果上一步無法響應(yīng)消息澄耍,調(diào)用- (id)forwardingTargetForSelector:(SEL)aSelector方法,將消息接受者轉(zhuǎn)發(fā)到另一個對象target(不能為self晌缘,否則死循環(huán))齐莲。
Normal Forwarding(普通消息轉(zhuǎn)發(fā)):如果上一步無法響應(yīng)消息:調(diào)用方法簽名- (NSMethodSignature?)methodSignatureForSelector:(SEL)aSelector,方法簽名目的將函數(shù)的參數(shù)類型和返回值封裝磷箕;如果返回非nil选酗,則創(chuàng)建一個NSInvocation對象利用方法簽名和selector封裝未被處理的消息,作為參數(shù)傳遞給- (void)forwardInvocation:(NSInvocation)anInvocation岳枷。這一步比較耗時芒填。
6、+load方法和+initialize方法空繁。load方法是首次加載類時調(diào)用殿衰,絕對只調(diào)用一次;initialize方法是首次給類發(fā)消息時調(diào)用盛泡,通常只調(diào)用一次闷祥,但如果它的子類初始化時未定義initialize方法,則會再調(diào)用一次它的initialize方法
7傲诵、實現(xiàn)類似京東下拉刷新(小人快跑)動畫凯砍,主要是通過shapelayer設(shè)置path,path怎么得到是畫出來還是勾勒出來不考慮掰吕,最核心的是通過strokestart和strokeend進行設(shè)置的果覆,下面直接說start和end代稱,講解一下start和end都是干嘛的:畫出path指定開始的path位置和結(jié)束path的位置殖熟,中間的path才是我們畫出來的,所以我們可以做一個在動的動畫斑响,就是控制path繪制的顯示來讓動畫顯示出來的菱属。
8钳榨、viewdidappear是在過場動畫結(jié)束后被調(diào)用 過場動畫的時間是0.35秒
9、[view?setExclusiveTouch:YES]; 這屬性的作用是同一個view內(nèi) 用來防止多個點同時觸摸
10纽门、Content Hugging Priority控制當(dāng)view frame>intrinsicContentSize時薛耻,是不是要縮小view 的size,此constraint試圖保持view的size不讓其變大赏陵;而Content Compression Resistancy Priority控制當(dāng)view frame<intrinsicContentSize時, 要不要截斷content饼齿,保持view frame size。 實際尺寸比設(shè)定尺寸大的時候才會去考慮壓縮優(yōu)先級蝙搔,實際尺寸比設(shè)定尺寸小的時候才會去考慮擁抱優(yōu)先級缕溉,此constraint試圖保持view的size不讓其變小。這兩個屬性都是針對于intrinsiccontentsize吃型,都是對于intrinsiccontentsize進行的操作证鸥。由此理解約束最后都會去確認intrinsiccontentsize是否可以縮小,這樣的布局方式勤晚。
11枉层、關(guān)于copy是否會增加引用計數(shù)的問題,這個主要是要說一下所copy的對象的copywithzone函數(shù)和mutablecopywithzone函數(shù)的實現(xiàn)赐写,是否會造成引用計數(shù)的增加鸟蜡,比如系統(tǒng)的nsarray和nsmutablearray,兩者使用copy的時候挺邀,nsarray只是簡單的增加引用計數(shù)并返回矩欠,而nsmutablearray卻會重新構(gòu)建一個對象返回回去,所以nsmutablearray copy 就不會增加引用計數(shù)悠夯,而當(dāng)調(diào)用mutablearray的時候癌淮,nsarray和nsmutablearray都會構(gòu)建一個新的nsmutablearray對象返回回去,所以copy是否增加引用計數(shù)是要看具體協(xié)議實現(xiàn)的沦补。
12乳蓄、關(guān)于runtime,先說變?yōu)榭蓤?zhí)行文件的過程夕膀,預(yù)編譯-編譯-匯編-鏈接=>可執(zhí)行文件虚倒,那么我們分辨看一下每一步的產(chǎn)物,預(yù)編譯是在做宏替換等操作产舞,然后編譯在oc會先由clang把oc代碼變?yōu)橐粋€語句樹魂奥,這個語句樹標(biāo)識著每一段都是干什么用的,然后llvm根據(jù)語句樹轉(zhuǎn)譯成為匯編語言易猫,然后匯編器把匯編語言轉(zhuǎn)譯成機器語言耻煤,得到的是一個目標(biāo)文件,然后進行鏈接,連接器主要就是把一些文件的undfind的”空白區(qū)域“進行填補哈蝇,然后把靜態(tài)庫也鏈接進來棺妓,最終把這些拷貝到一個文件里面,這就是可執(zhí)行文件炮赦×埽總體上目標(biāo)文件和可執(zhí)行文件結(jié)構(gòu)差不多,這里說一下目標(biāo)文件吠勘,目標(biāo)文件里面有機器指令碼性芬、數(shù)據(jù)、符號表剧防、調(diào)試信息植锉、字符串等,會以segment的形式進行存儲诵姜,機器指令碼存放在代碼段汽煮,全局變量、靜態(tài)變量存放在數(shù)據(jù)段棚唆,機器指令碼其實就是所寫的代碼暇赤,關(guān)于全局變量靜態(tài)變量還有函數(shù)地址是何時確定的問題,是在編譯器知道偏移量宵凌,然后編譯完以后鞋囊,鏈接器開始鏈接編譯后的文件,確定每個文件的段地址瞎惫,段地址+偏移量來確定的具體變量的地址溜腐,要說的是這些地址在開始加載程序的時候,內(nèi)存映射的地址是一樣的9侠Mσ妗!乘寒,局部變量的地址是靠對應(yīng)的函數(shù)棧的匯編操作來確定的望众。還有就是編譯的時候,有些外聯(lián)的變量無法確定偏移地址伞辛,編譯器就會導(dǎo)出一個重定向表烂翰,這個由編譯器去處理,所以編譯會導(dǎo)出確定表蚤氏、非確定表甘耿、重定向表。
13竿滨、self和super 調(diào)用class區(qū)別:super會調(diào)用obj_msgsuper 佳恬,target是一個結(jié)構(gòu)體捏境,里面是當(dāng)前對象和superclass,調(diào)用的時候去尋找superclass的方法殿怜,但是沒找到典蝌,去找nsobject里面的曙砂,找到后用結(jié)構(gòu)體的第一個元素去調(diào)用头谜,也就是當(dāng)前對象去調(diào)用,所以輸出就是子類鸠澈;相應(yīng)的如果在父類里面能找到方法柱告,那么就直接調(diào)用,而子類調(diào)用父類的方法笑陈,這個過程就是方法調(diào)用的過程际度。為何這樣究其原因接收消息的實體一直都是一個,也就是當(dāng)前對象涵妥。我覺得msgsuper和msg的區(qū)別就是不用去當(dāng)前類里面去尋找了乖菱,而是直接就去父類尋找,哈哈蓬网。
14窒所、ios內(nèi)存組織結(jié)構(gòu),在鏈接后確認的代碼段數(shù)據(jù)段的內(nèi)容帆锋,在運行的時候會有局部變量吵取,這個就是堆棧里面放置,要明確的是棧的生長方向是高到低锯厢,堆的生長方向是低到高皮官;
15、關(guān)于下載任務(wù)多線程和單線程哪個快的問題实辑,如果線程下載任務(wù)能達到網(wǎng)卡上限得話捺氢,單線程和多線程沒有太多性能差距,但現(xiàn)實中很少能達到網(wǎng)卡瓶頸剪撬,所以一個下載資源只能用到一部分帶寬摄乒,而多線程的話就可以盡可能的占用帶寬,所以多線程的速度要快婿奔。說白了就是單位時間內(nèi)使用的帶寬越多速度越快缺狠,而多線程就是增加了占用的帶寬。以上理解的有問題萍摊,但是不失為一種理解的過程挤茄,其實底層已經(jīng)使用kqueue做了異步io,不管是并發(fā)還是串行的任務(wù)都會由內(nèi)核進行數(shù)據(jù)的io操作冰木,這時候只分阻塞還是非阻塞兩種方式穷劈,阻塞的時候就是等待任務(wù)完成笼恰,非阻塞就是何時io緩存里面有數(shù)據(jù)就繼續(xù)處理,沒有了就停止等有了數(shù)據(jù)再次進行處理歇终,這也就是咱們理解的同步與異步社证,值得說的這里的阻塞是指接收這一端的操作,而不是發(fā)送那一端的阻塞评凝。
16追葡、總結(jié)一下線程相關(guān)的感悟,先說進程的作用奕短,計算機運行的時候會分出很多進程宜肉,進程包含代碼和資源,cpu就會處理代碼翎碑,可以猜想一下谬返,進程沒有出現(xiàn)之前,所有的代碼和資源都放在一起日杈,這樣如果是多個應(yīng)用不能把代碼都放到一起吧遣铝?所以說進程的目的就是代碼分離和資源的隔離,還有一個就是如果要做很多任務(wù)莉擒,那么就需要多進程來進行處理酿炸。那線程的目的也是類似,在手機端啰劲,ui主線程里面執(zhí)行讀取文件操作梁沧,那么主線程就要被卡住了,所以說要多個線程來做異步蝇裤,把耗時操作放到其他線程廷支,所以說多個任務(wù)還要一起執(zhí)行多線程是一個很好的辦法!再看http請求栓辜,要說一個命題:http請求會啟動線程去處理恋拍。為何要這么說呢?因為http請求很明顯是一個耗時的操作藕甩,如果在ui線程進行網(wǎng)絡(luò)請求勢必要使用while循環(huán)來不間斷獲取response.data施敢,很明顯ui線程會被卡住,所以http請求就要就要異步的去進行處理狭莱。更多的說一下系統(tǒng)的api僵娃,cfnetwork或者socket來做處理的時候不會自己去創(chuàng)建線程(因為網(wǎng)絡(luò)請求是網(wǎng)絡(luò)請求,線程是線程腋妙,只不過網(wǎng)絡(luò)請求是一個耗時操作默怨,不想卡住當(dāng)前線程,所以才會使用異步來做處理)骤素,而系統(tǒng)的urlsession匙睹、URLHTTPconnect內(nèi)部已經(jīng)封裝了線程的異步處理愚屁,所以說呢 多線程就真的是想做任務(wù)而存在的,與網(wǎng)絡(luò)請求或者文件讀取是沒關(guān)系的痕檬。
17霎槐、弱引用的實現(xiàn)結(jié)構(gòu) 是一個weaktable里面存放著weakentry數(shù)組,而這個數(shù)組的entry是通過index尋找的梦谜,這個index是通過掩碼計算的hash值丘跌,尋找到的entry其實就是這個newobj所對應(yīng)的散列表,所以這就能看出來是散列表套散列表的數(shù)據(jù)結(jié)構(gòu)改淑。那么創(chuàng)建弱引用對象的時候碍岔,就是查看是否存在對應(yīng)的entry如果沒有在table->entrys里insert一個entry并查看是否需要grow這個散列表浴讯,這個entry是一個散列表朵夏,里面存儲的是弱引用的指針;刪除弱引用的時候榆纽,就把對應(yīng)的entry里面的弱引用置為nil仰猖,并減少計數(shù)范圍,并且判斷這個entry是否為empty奈籽,如果是空的就刪除這個entry饥侵。當(dāng)newobj銷毀的時候,當(dāng)調(diào)用dealloc的時候衣屏,里面會有一個weakclear方法躏升,就會把newobj對應(yīng)的entry的弱引用置為nil,并且刪除掉entry狼忱。