<h1>1矢门、viewcontroller的一些方法的說(shuō)明viewDidLoad,viewWillDisappear, viewWillAppear方法的 順序和作用拘央?</h1>
viewWillAppear:視圖即將可見(jiàn)時(shí)調(diào)用。默認(rèn)情況下不執(zhí)行任何操作
viewDidAppear:視圖已完全過(guò)渡到屏幕上時(shí)調(diào)用
viewWillDisappear:視圖被駁回時(shí)調(diào)用善已,覆蓋或以其他方式隱藏谴轮。默認(rèn)情況下不執(zhí)行任何操作
viewDidDisappear:視圖被駁回后調(diào)用挂洛,覆蓋或以其他方式隱藏。默認(rèn)情況下不執(zhí)行任何操作loadView; .這是當(dāng)他們沒(méi)有正在使用nib視圖頁(yè)面超营,子類將會(huì)創(chuàng)建自己的自定義視圖層鸳玩。絕不能直接調(diào)用。
viewDidLoad:在視圖加載后被調(diào)用演闭,如果是在代碼中創(chuàng)建的視圖加載器不跟,他將會(huì)在loadView方法后被調(diào)用,如果是從nib視圖頁(yè)面輸出米碰,他將會(huì)在視圖設(shè)置好后后被調(diào)用窝革。
「initWithNibName: bundle:」載入nib檔案來(lái)初始化「loadView」載入視圖「viewDidLoad」在載入視圖至內(nèi)存后會(huì)呼叫的方法「viewDidUnload」在視圖從內(nèi)存中釋放后會(huì)呼叫的方法 (當(dāng)內(nèi)存過(guò)低,釋放一些不需要的視圖時(shí)調(diào)用)
「viewWillAppear」當(dāng)收到視圖在視窗將可見(jiàn)時(shí)的通知會(huì)呼叫的方法
「viewDidAppear」當(dāng)收到視圖在視窗已可見(jiàn)時(shí)的通知會(huì)呼叫的方法
「viewWillDisappear」當(dāng)收到視圖將去除吕座、被覆蓋或隱藏于視窗時(shí)的通知會(huì)呼叫的方法
「viewDidDisappear」當(dāng)收到視圖已去除虐译、被覆蓋或隱藏于視窗時(shí)的通知會(huì)呼叫的方法
「didReceiveMemoryWarning」收到系統(tǒng)傳來(lái)的內(nèi)存警告通知后會(huì)執(zhí)行的方法
「shouldAutorotateToInterfaceOrientation」是否支持不同方向的旋轉(zhuǎn)視圖
「willAnimateRotationToInterfaceOrientation」在進(jìn)行旋轉(zhuǎn)視圖前的會(huì)執(zhí)行的方法(用于調(diào)整旋轉(zhuǎn)視圖之用)
代碼的執(zhí)行順序
1、 alloc 創(chuàng)建對(duì)象吴趴,分配空間
2漆诽、init (initWithNibName) 初始化對(duì)象,初始化數(shù)據(jù)
3锣枝、loadView 從nib載入視圖 厢拭,通常這一步不需要去干涉。除非你沒(méi)有使用xib文件創(chuàng)建視圖
4惊橱、viewDidLoad 載入完成蚪腐,可以進(jìn)行自定義數(shù)據(jù)以及動(dòng)態(tài)創(chuàng)建其他控件
5、viewWillAppear 視圖將出現(xiàn)在屏幕之前税朴,馬上這個(gè)視圖就會(huì)被展現(xiàn)在屏幕上了
6受神、viewDidAppear 視圖已在屏幕上渲染完成當(dāng)一個(gè)視圖被移除屏幕并且銷毀的時(shí)候的執(zhí)行順序,這個(gè)順序差不多和上面的相反
1夺欲、viewWillDisappear 視圖將被從屏幕上移除之前執(zhí)行
2荠列、viewDidDisappear 視圖已經(jīng)被從屏幕上移除,用戶看不到這個(gè)視圖了
3师抄、dealloc 視圖被銷毀,此處需要對(duì)你在init和viewDidLoad中創(chuàng)建的對(duì)象進(jìn)行釋放
<h1>2、什么是key window涵但?</h1>
一個(gè)窗口當(dāng)前能接受鍵盤和非觸摸事件時(shí),便被認(rèn)為是主窗口帖蔓。而觸摸事件則被投遞到觸摸發(fā)生的窗口矮瘟,沒(méi)有相應(yīng)坐標(biāo)值的事件被投遞到主窗口。同一時(shí)刻只有一個(gè)窗口是主窗口塑娇。
<h1>3澈侠、談一談你是怎么封裝view的</h1>
1> 先添加所需子控件
2> 再接收模型數(shù)據(jù)根據(jù)模型數(shù)據(jù)設(shè)置子控件數(shù)據(jù)和位置
3> 簡(jiǎn)而言之, 自己的事情自己做, 把不需要暴露出去的封裝起來(lái)
<h1>4、簡(jiǎn)單說(shuō)一下APP的啟動(dòng)過(guò)程,從main文件開(kāi)始說(shuō)起</h1>
程序啟動(dòng)分為兩類:1.有storyboard 2.沒(méi)有storyboard
有storyboard情況下:
1.main函數(shù)
2.UIApplicationMain
* 創(chuàng)建UIApplication對(duì)象
* 創(chuàng)建UIApplication的delegate對(duì)象
3.根據(jù)Info.plist獲得Main.storyboard的文件名,加載Main.storyboard(有storyboard)
* 創(chuàng)建UIWindow
* 創(chuàng)建和設(shè)置UIWindow的rootViewController
* 顯示窗口
沒(méi)有storyboard情況下:
1.main函數(shù)
2.UIApplicationMain
* 創(chuàng)建UIApplication對(duì)象
* 創(chuàng)建UIApplication的delegate對(duì)象
3.delegate對(duì)象開(kāi)始處理(監(jiān)聽(tīng))系統(tǒng)事件(沒(méi)有storyboard)
* 程序啟動(dòng)完畢的時(shí)候, 就會(huì)調(diào)用代理的application:didFinishLaunchingWithOptions:方法
* 在application:didFinishLaunchingWithOptions:中創(chuàng)建UIWindow
* 創(chuàng)建和設(shè)置UIWindow的rootViewController
* 顯示窗口
<h1>5埋酬、怎么解決緩存池滿的問(wèn)題(cell)</h1>
iOS中不存在緩存池滿的情況哨啃,因?yàn)橥ǔN覀僫os中開(kāi)發(fā),對(duì)象都是在需要的時(shí)候才會(huì)創(chuàng)建写妥,有種常用的說(shuō)話叫做懶加載拳球,還有在UITableView中一般只會(huì)創(chuàng)建剛開(kāi)始出現(xiàn)在屏幕中的cell,之后都是從緩存池里取珍特,不會(huì)在創(chuàng)建新對(duì)象祝峻。緩存池里最多也就一兩個(gè)對(duì)象,緩存池滿的這種情況一般在開(kāi)發(fā)java中比較常見(jiàn)次坡,java中一般把最近最少使用的對(duì)象先釋放呼猪。
<h1>6、UIButton與UITableView的層級(jí)結(jié)構(gòu)</h1>
UIButton為:UIButton > UIControl > UIView > UIResponder > NSObject
UITableView為:UITableView > UIScrollView > UIView > UIResponder > NSObject
<h1>7砸琅、設(shè)置scroll view的contensize能在Viewdidload里設(shè)置么,為什么</h1>
1> 一般情況下可以設(shè)置在viewDidLoad中宋距,但在autolayout下,系統(tǒng)會(huì)在viewDidAppear之前根據(jù)subview的constraint重新計(jì)算scrollview的contentsize症脂。 這就是為什么谚赎,在viewdidload里面手動(dòng)設(shè)置了contentsize沒(méi)用。因?yàn)樵诤竺嬗张瘢瑫?huì)再重新計(jì)算一次壶唤,前面手動(dòng)設(shè)置的值會(huì)被覆蓋掉。
2 > 解決辦法就是:
去除autolayout選項(xiàng)棕所,自己手動(dòng)設(shè)置contentsize
3> 如果要使用autolayout闸盔,要么自己設(shè)置完subview的constraint,然后讓系統(tǒng)自動(dòng)根據(jù)constraint計(jì)算出contentsize琳省。要么就在viewDidAppear里面自己手動(dòng)設(shè)置contentsize迎吵。
<h1>8躲撰、簡(jiǎn)述你對(duì)UIView、UIWindow和CALayer的理解</h1>
1击费、UIView: 屬于UIkit.framework框架,負(fù)責(zé)渲染矩形區(qū)域的內(nèi)容,為矩形區(qū)域添加動(dòng)畫,響應(yīng)區(qū)域的觸摸事件,布局和管理一個(gè)或多個(gè)子視圖
2拢蛋、UIWindow:屬于UIKit.framework框架,是一種特殊的UIView,通常在一個(gè)程序中只會(huì)有一個(gè)UIWindow,但可以手動(dòng)創(chuàng)建多個(gè)UIWindow,同時(shí)加到程序里面。
UIWindow在程序中主要起到三個(gè)作用:
a蔫巩、 作為容器,包含app所要顯示的所有視圖
b谆棱、傳遞觸摸消息到程序中view和其他對(duì)象
c、與UIViewController協(xié)同工作,方便完成設(shè)備方向旋轉(zhuǎn)的支持
3圆仔、CAlayer:屬于QuartzCore.framework,是用來(lái)繪制內(nèi)容的,對(duì)內(nèi)容進(jìn)行動(dòng)畫處理依賴與UIView來(lái)進(jìn)行顯示,不能處理用戶事件垃瞧。
4、UIView和CALayer是相互依賴的,UIView依賴CALayer提供內(nèi)容,CALayer依賴UIView的容器顯示繪制內(nèi)容坪郭。
5皆警、(補(bǔ)充)UIViewController:每個(gè)視圖控制器都有一個(gè)自帶的視圖,并且負(fù)責(zé)這個(gè)視圖相關(guān)的一切事務(wù)。方便管理視圖中的子視圖,負(fù)責(zé)model與view的通信;檢測(cè)設(shè)備旋轉(zhuǎn)以及內(nèi)存警告;是所有視圖控制類的積累,定義了控制器的基本功能截粗。
<h1>9、frame和bounds有什么不同鸵隧?(Difference between frame and bounds?)</h1>
1> frame指的是:該view在父view坐標(biāo)系統(tǒng)中的位置和大谐衤蕖(參照點(diǎn)是父親的坐標(biāo)系統(tǒng))
2> bounds指的是:該view在本身坐標(biāo)系統(tǒng)中的位置和大小(參照點(diǎn)是本身坐標(biāo)系統(tǒng))
<h1>10豆瘫、響應(yīng)者鏈條? (What is responder chain?)</h1>
1> 事件響應(yīng)鏈珊蟀。包括點(diǎn)擊事件,畫面刷新事件等外驱。在視圖棧內(nèi)從上至下育灸,或者從下之上傳播. 可以說(shuō)點(diǎn)事件的分發(fā),傳遞以及處理昵宇。具體可以去看下touch事件這塊磅崭。
2> 首先解釋響應(yīng)者鏈的概念
a、UIResponder類瓦哎,是UIKIT中一個(gè)用于處理事件響應(yīng)的基類砸喻。窗口上的所有事件觸發(fā),都由該類響應(yīng)(即事件處理入口)蒋譬。所以割岛,窗口上的View及控制器都是派生于該類的,例如UIView犯助、UIViewController等癣漆。
b、調(diào)用UIResponder類提供的方法或?qū)傩约谅颍覀兙涂梢圆蹲降酱翱谏系乃许憫?yīng)事件惠爽,并進(jìn)行處理癌蓖。
c、響應(yīng)者鏈條是由多個(gè)響應(yīng)者對(duì)象連接起來(lái)的鏈條疆股,其中響應(yīng)者對(duì)象是能處理事件的對(duì)象费坊,所有的View和ViewController都是響應(yīng)者對(duì)象,利用響應(yīng)者鏈條能讓多個(gè)控件處理同一個(gè)觸摸事件.
3> 事件傳遞機(jī)制:
如果當(dāng)前view不能處理當(dāng)前事件旬痹,那么事件將會(huì)沿著響應(yīng)者鏈(Responder Chain)進(jìn)行傳遞附井,知道遇到能處理該事件的響應(yīng)者(Responsder Object)。
- 接收事件的initial view如果不能處理該事件并且她不是頂層的View两残,則事件會(huì)往它的父View進(jìn)行傳遞永毅。
- initial view的父View獲取事件后如果仍不能處理,則繼續(xù)往上傳遞人弓,循環(huán)這個(gè)過(guò)程沼死。如果頂層的View還是不能處理這個(gè)事件的話,則會(huì)將事件傳遞給它們的ViewController崔赌,
- 如果ViewController也不能處理意蛀,則傳遞給Window(UIWindow),此時(shí)Window不能處理的話就將事件傳遞UIApplication健芭,最后如果連Application也不能處理县钥,則廢棄該事件
<h1>11、ViewController的loadView,viewDidLoad,viewDidUnload分別是在什么時(shí)候調(diào)用的慈迈?在自定義ViewController的時(shí)候這幾個(gè)函數(shù)里面應(yīng)該做什么工作若贮?</h1>
1> viewDidLoad在view從nib文件初始化時(shí)調(diào)用,
2> loadView在controller的view為nil時(shí)調(diào)用痒留。
3> 此方法在編程實(shí)現(xiàn)view時(shí)調(diào)用, view控制器默認(rèn)會(huì)注冊(cè)memory warning notification,當(dāng)viewcontroller的任何view沒(méi)有用的時(shí)候谴麦,viewDidUnload會(huì)被調(diào)用,在這里實(shí)現(xiàn)將retain的view release,如果是retain的IBOutlet view屬性則不要在這里release,IBOutlet會(huì)負(fù)責(zé)release伸头。
<h1>12匾效、UITableView的重用機(jī)制?(或者如何在一個(gè)view上顯示多個(gè)tableView,tableView要求不同的數(shù)據(jù)源以及不同的樣式 (要求自定義cell), 如何組織各個(gè)tableView的delegate和dataSource?請(qǐng)說(shuō)說(shuō)實(shí)現(xiàn)思路?)</h1>
1> 查看UITableView頭文件,會(huì)找到NSMutableArray *visiableCells,和NSMutableArray * reusableTableCells兩個(gè)結(jié)構(gòu)。
2> visiableCells內(nèi)保存當(dāng)前顯示的cells,reusableTableCells保存可重用的cells恤磷。
3> TableView顯示之初,reusableTableCells為空,那么[tableView dequeueReusableCellWithIdentifier:CellIdentifier]返回nil弧轧。
4> 開(kāi)始的cell都通過(guò) [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]來(lái)創(chuàng)建。
而且cellForRowAtIndexPath只是調(diào)用最大顯示cell數(shù)的次數(shù)碗殷。 比如:有100條數(shù)據(jù),iPhone一屏最多顯示10個(gè)cell精绎。
5> 程序最開(kāi)始顯示TableView的情況是:
-用[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]創(chuàng)建10次cell,并給cell指定同樣的重用標(biāo)識(shí)(當(dāng)然,可以為不同顯示類型的cell指定不同的標(biāo)識(shí))。并且10個(gè)cell全部都加入到visiableCells數(shù)組,reusableTableCells為空锌妻。
-向下拖動(dòng)tableView,當(dāng)cell1完全移出屏幕,并且cell11(它也是alloc出來(lái)的,原因同上)完全顯示出來(lái)的時(shí)候代乃。cell11加入到visiableCells,cell1移出visiableCells,cell1加入到reusableTableCells。
-接著向下拖動(dòng)tableView,因?yàn)閞eusableTableCells中已經(jīng)有值,所以,當(dāng)需要顯示新的cell, cellForRowAtIndexPath再次被調(diào)用的時(shí)候,[tableView dequeueReusableCellWithIdentifier:CellIdentifier],返回cell1。 cell1加入到visiableCells,cell1 移出reusableTableCells;cell2移出 visiableCells,cell2加入到reusableTableCells搁吓。之后再需要顯示的Cell就可 以正常重用了.
-注意:配置Cell的時(shí)候一定要注意原茅,對(duì)取出的重用的cell做重新賦值,不要遺留老數(shù)據(jù)堕仔。
<h1>13擂橘、UITableView的性能優(yōu)化? 滑動(dòng)的時(shí)候有種卡的感覺(jué)是為什么?怎么解決摩骨?</h1>
在使用第三方應(yīng)用時(shí)通贞,卻經(jīng)常遇到性能上的問(wèn)題,普遍表現(xiàn)在滾動(dòng)時(shí)比較卡恼五,特別是cell中包含圖片的情況時(shí)昌罩。
實(shí)際上針對(duì)性地優(yōu)化一下就可以解決tableView滑動(dòng)的時(shí)候卡頓的問(wèn)題:
1> 使用不透明視圖。不透明的視圖可以提高渲染的速度灾馒【ビ茫可以將cell及其子視圖的opaque屬性設(shè)為YES(默認(rèn)值)。
2> 不要重復(fù)創(chuàng)建不必要的cell睬罗。UITableView只需要一屏幕的UITableViewCell對(duì)象即可轨功。因此在cell不可見(jiàn)時(shí),可以將其緩存起來(lái)容达,而在需要時(shí)繼續(xù)使用它即可夯辖。注意:cell被重用時(shí),需要調(diào)用setNeedsDisplayInRect:或setNeedsDisplay方法重繪cell董饰。
3> 減少動(dòng)畫效果的使用,最好不要使用insertRowsAtIndexPaths:withRowAnimation:方法圆米,而是直接調(diào)用reloadData方法卒暂。
4> 減少視圖的數(shù)目。Cell包含了textLabel娄帖、detailTextLabel和imageView等view也祠,而你還可以自定義一些視圖放在它的contentView里,創(chuàng)建它會(huì)消耗較多資源近速,并且也影響渲染的性能诈嘿。
5> cell包含圖片,且數(shù)目較多削葱,使用自定義的cell速度會(huì)比使用默認(rèn)的要快奖亚。繼承UITableViewCell,重寫drawRect方法:- (void)drawRect:(CGRect)rect { if (image) { [image drawAtPoint:imagePoint]; self.image = nil; } else { [placeHolder drawAtPoint:imagePoint]; } [text drawInRect:textRect withFont:font lineBreakMode:UILineBreakModeTailTruncation]; }
不過(guò)這樣一來(lái)析砸,你會(huì)發(fā)現(xiàn)選中一行后昔字,這個(gè)cell就變藍(lán)了,其中的內(nèi)容就被擋住了首繁。最簡(jiǎn)單的方法就是將cell的selectionStyle屬性設(shè)為UITableViewCellSelectionStyleNone作郭,這樣就不會(huì)被高亮了陨囊。
-不需要與用戶交互時(shí),使用CALayer夹攒,將內(nèi)容繪制到layer上蜘醋,然后對(duì)cell的contentView.layer調(diào)用addSublayer:方法。這個(gè)例子中咏尝,layer并不會(huì)顯著影響性能压语,但如果layer透明,或者有圓角状土、變形等效果无蜂,就會(huì)影響到繪制速度了。解決辦法可參見(jiàn)后面的預(yù)渲染圖像蒙谓。
6> 不要做多余的繪制工作斥季。在實(shí)現(xiàn)drawRect:的時(shí)候,它的rect參數(shù)就是需要繪制的區(qū)域累驮,這個(gè)區(qū)域之外的不需要進(jìn)行繪制酣倾。
7> 預(yù)渲染圖像。你會(huì)發(fā)現(xiàn)即使做到了上述幾點(diǎn)谤专,當(dāng)新的圖像出現(xiàn)時(shí)躁锡,仍然會(huì)有短暫的停頓現(xiàn)象。解決的辦法就是在圖形上下文中畫置侍,導(dǎo)出成UIImage對(duì)象映之,然后再繪制到屏幕。(頭像圓角蜡坊,或者其他變形的時(shí)候杠输,用圖形上下文能提高性能。)異步繪制
8> 不要阻塞主線程秕衙。tableview在更新數(shù)據(jù)時(shí)蠢甲,整個(gè)界面卡住不動(dòng),完全不響應(yīng)用戶請(qǐng)求据忘。常見(jiàn)的是網(wǎng)絡(luò)請(qǐng)求鹦牛,等待時(shí)間長(zhǎng)待數(shù)秒。
解決方案:使用多線程勇吊,讓子線程去執(zhí)行這些函數(shù)或方法曼追。
注意:當(dāng)下載線程數(shù)超過(guò)2時(shí),會(huì)顯著影響主線程的性能汉规。所以在不需要響應(yīng)用戶請(qǐng)求時(shí)拉鹃,下載線程數(shù)可以增加到5,不建議再加了,以加快下載速度膏燕。如果用戶正在交互钥屈,應(yīng)把線程數(shù)量控制在2個(gè)以內(nèi)。
9> 提前計(jì)算并緩存好高度坝辫,因?yàn)閔eightforrowatindexpath調(diào)用非常頻繁
10> 選擇正確的數(shù)據(jù)結(jié)構(gòu):學(xué)會(huì)選擇對(duì)業(yè)務(wù)場(chǎng)景最合適的數(shù)組結(jié)構(gòu)是寫出高效代碼的基礎(chǔ)篷就。比如,數(shù)組: 有序的一組值近忙。使用索引來(lái)查詢很快竭业,使用值查詢很慢,插入/刪除很慢及舍。字典: 存儲(chǔ)鍵值對(duì)未辆,用鍵來(lái)查找比較快。集合: 無(wú)序的一組值锯玛,用值來(lái)查找很快咐柜,插入/刪除很快。
11> gzip/zip壓縮:當(dāng)從服務(wù)端下載相關(guān)附件時(shí)攘残,可以通過(guò)gzip/zip壓縮后再下載拙友,使得內(nèi)存更小,下載速度也更快歼郭。
<h1>14遗契、談?wù)剋ebView</h1>
iOS開(kāi)發(fā)中webview和native code的配合上的一些經(jīng)驗(yàn)和技巧。
webview與運(yùn)維成本低病曾,更新幾乎不依賴App的版本牍蜂;但在交互和性能上與跟native code有很大差距。
native code與之對(duì)應(yīng)泰涂。
HTML5確實(shí)給web帶入了一個(gè)新時(shí)代鲫竞。這個(gè)時(shí)代是什么,web app负敏。也就是說(shuō),只有脫離native的這個(gè)前提秘蛇,在瀏覽器的環(huán)境下其做,HTML5的意義才能顯現(xiàn),而我們討論iOS App的時(shí)候赁还,HTML5顯然沒(méi)什么意義妖泄。
不管是用webview還是native code,兩個(gè)原則:
1> 用戶體驗(yàn)不打折
2> 運(yùn)維成本低
為什么不提開(kāi)發(fā)成本艘策。因?yàn)樽鰓eb開(kāi)發(fā)和iOS開(kāi)發(fā)根本就是兩回事蹈胡。當(dāng)然,web開(kāi)發(fā)發(fā)展了這么多年,對(duì)于某些功能實(shí)現(xiàn)是要比native app快罚渐。但多數(shù)情況却汉,同一個(gè)功能,對(duì)于iOS開(kāi)發(fā)者和web開(kāi)發(fā)者荷并,用各自擅長(zhǎng)的方式開(kāi)發(fā)成本都最低合砂,所以說(shuō)某個(gè)功能開(kāi)發(fā)成本低,往往是一個(gè)偽命題源织。
剛剛說(shuō)了翩伪,webview的優(yōu)勢(shì)在于更新不依賴版本,那么在一款A(yù)pp中谈息,只有會(huì)頻繁更新的界面考慮webview才有意義缘屹。那么哪些界面會(huì)頻繁更新,這就要因App而異了侠仇。
1> 首頁(yè)轻姿。首頁(yè)資源可謂必爭(zhēng)之地,內(nèi)容一天一換是正掣嫡埃現(xiàn)象踢代,一天幾換也不稀奇。而如果僅僅是內(nèi)容的更換嗅骄,非要上個(gè)webview就顯得有些激進(jìn)了胳挎。而事實(shí)上首頁(yè)的變化千奇百怪,逢年過(guò)節(jié)變個(gè)臉溺森,特殊情況掛個(gè)公告慕爬,偶爾還要特批強(qiáng)推一把某個(gè)業(yè)務(wù),等等屏积。此前医窿,我在設(shè)計(jì)App首頁(yè)的時(shí)候,把首頁(yè)配置設(shè)計(jì)的非常復(fù)雜炊林。App端要處理n種情況姥卢,n各參數(shù),server端要記住n種規(guī)則渣聚,直到一天独榴,我崩潰了,把首頁(yè)完全換成webview奕枝,才豁然開(kāi)朗棺榔。
2> 活動(dòng)頁(yè)。做互聯(lián)網(wǎng)都知道隘道,活動(dòng)症歇,是一個(gè)最常見(jiàn)的運(yùn)營(yíng)手段郎笆。特點(diǎn)是,周期短忘晤,功能少宛蚓,但基本不能復(fù)用。這些特點(diǎn)都標(biāo)識(shí)了活動(dòng)不適合做native德频,要用webview實(shí)現(xiàn)苍息。即使有人告訴你說(shuō),我的活動(dòng)是一個(gè)長(zhǎng)期活動(dòng)而且形式不變壹置,也不要相信他竞思。因?yàn)樵诘诙冢谌诔ぃ谒钠谒麜?huì)分別加上一些非常詭異盖喷,卻有很合理的小變更,而這些變更是你在那個(gè)版本根本無(wú)法實(shí)現(xiàn)的难咕。
3> 試水的新功能课梳。這種界面,往往設(shè)計(jì)不成熟余佃,需要在運(yùn)行過(guò)程中不斷收集用戶反饋暮刃,更新升級(jí),甚至決定去留爆土。所以椭懊,只有webview才能hold住如此不穩(wěn)定的功能。切記在一個(gè)功能還沒(méi)有確定之前步势,不要大張旗鼓單位開(kāi)發(fā)native code氧猬,要知道,你寫的這些代碼坏瘩,三天后就要改一遍盅抚,而且要發(fā)布上線。
4> 富文本內(nèi)容倔矾。這個(gè)不用多說(shuō)了吧妄均,按照HTML的常用標(biāo)簽做一個(gè)webtext可不是小工程。而且富文本的變化太多了哪自,一點(diǎn)無(wú)法匹配丰包,都會(huì)導(dǎo)致整個(gè)界面巨丑。
OK提陶,上邊說(shuō)了我認(rèn)為最該使用webview的4個(gè)界面烫沙,分別帶有不同的特點(diǎn)匹层,但webview的交互是個(gè)短板隙笆,因此webview在一個(gè)App中锌蓄,只能作為界面,不允許在界面中出現(xiàn)動(dòng)作撑柔。而一個(gè)webview的界面如何跟native code結(jié)合起來(lái)呢瘸爽,我的答案是,超鏈接铅忿。在webview上點(diǎn)擊超鏈接剪决,會(huì)調(diào)用webview delegate的shouldload方法,自這里攔截請(qǐng)求檀训,進(jìn)行處理柑潦。由于webview的鏈接都是URL,因此我建議峻凫,把整個(gè)App的界面都用URL管理起來(lái)渗鬼。
1> 長(zhǎng)相問(wèn)題,webview很難長(zhǎng)成native的view荧琼。方案:長(zhǎng)不成也要裝成譬胎。在一些情況下,禁用webview滾動(dòng)命锄,使用滾動(dòng)框架(iScroll不錯(cuò))去實(shí)現(xiàn)堰乔。webview上下留出200pixel的空白背景,y從-200開(kāi)始脐恩。否則大家知道镐侯,webview上下會(huì)有陰影的背景,不藏起來(lái)會(huì)很丑被盈。等等析孽,還有很多其他的方法去偽裝webview,是要視情景而用只怎。
2> cell中嵌套webview袜瞬,在oc中調(diào)用js獲取web的高度, CGFloat height = [[self.webView stringByEvaluatingJavaScriptFromString:@"document.body.offsetHeight"] floatValue];在通過(guò)webViewDidFinishLoad里面更新行高身堡。
<h1>15邓尤、awakeFromNib與viewdidload區(qū)別</h1>
awakefromnib:當(dāng).nib文件被加載的時(shí)候,會(huì)發(fā)送一個(gè)awakefromnib消息到.nib文件中的每個(gè)對(duì)象贴谎,每個(gè)對(duì)象都可以定義自己的awakefromnib函數(shù)來(lái)響應(yīng)這個(gè)消息汞扎,執(zhí)行必要操作。也就是說(shuō) 通過(guò).nib文件創(chuàng)建view對(duì)象執(zhí)行awakefromnib
viewdidload:當(dāng)view對(duì)象被加載到內(nèi)存就會(huì)執(zhí)行viewdidload擅这,不管是通過(guò)nib還是代碼形式澈魄,創(chuàng)建對(duì)象就會(huì)執(zhí)行viewdidload
<h1>16、layoutSubview何時(shí)調(diào)用?</h1>
初始化init方法時(shí)不會(huì)觸發(fā)
滾動(dòng)uiscrollview觸發(fā)
旋轉(zhuǎn)屏幕觸發(fā)
改變view的值觸發(fā)仲翎,前提是frame改變了
改變uiview的大小觸發(fā)
<h1>17痹扇、viewcontroller的didreceivememorywaring在什么時(shí)候調(diào)用 默認(rèn)操作是什么</h1>
應(yīng)用程序收到來(lái)自系統(tǒng)的內(nèi)存警告時(shí)铛漓,調(diào)用didreceivememorywaring方法
默認(rèn)做法:控制器上的view不再窗口上顯示時(shí),調(diào)用viewWillUnload鲫构,直接銷毀view浓恶,并調(diào)用viewdidunload
<h1>18、UIWindow和UIView和 CALayer 的聯(lián)系和區(qū)別?</h1>
1> UIView是視圖的基類结笨,UIViewController是視圖控制器的基類包晰,UIResponder是表示一個(gè)可以在屏幕上響應(yīng)觸摸事件的對(duì)象;
2> UIwindow是UIView的子類炕吸,UIWindow的主要作用:一是提供一個(gè)區(qū)域來(lái)顯示UIView伐憾,二是將事件(event)的分發(fā)給UIView,一個(gè)應(yīng)用基本上只有一個(gè)UIWindow.
圖層不會(huì)直接渲染到屏幕上赫模,UIView是iOS系統(tǒng)中界面元素的基礎(chǔ)塞耕,所有的界面元素都是繼承自它。它本身完全是由CoreAnimation來(lái)實(shí)現(xiàn)的嘴瓤。它真正的繪圖部分扫外,是由一個(gè)CALayer類來(lái)管理。UIView本身更像是一個(gè)CALayer的管理器廓脆。一個(gè)UIView上可以有n個(gè)CALayer筛谚,每個(gè)layer顯示一種東西,增強(qiáng)UIView的展現(xiàn)能力停忿。
3> 都可以顯示屏幕效果
4> 如果需要用戶交互就要用UIVIew,其可接收觸摸事件(繼承UIResponder),而CALayer不能接收觸摸事件
5> 如果沒(méi)有用戶交互可選用CALayer,因?yàn)槠渌趲?kù)較小,占用的資源較少
<h1>19驾讲、UIScrollView</h1>
contentsize 內(nèi)容視圖的尺寸
contentoffset 內(nèi)容視圖當(dāng)前位置相對(duì)滾動(dòng)視圖frame的偏移量
contentinset 內(nèi)容視圖相對(duì)滾動(dòng)視圖frame的展示原點(diǎn)
<h1>20、如何實(shí)現(xiàn)瀑布流,流水布局</h1>
1> 使用UICollectionView
2> 使用自定義的FlowLayout
3> 需要在layoutAttributesForElementsInRect中設(shè)置自定義的布局(item的frame)
4> 在 prepareLayout中計(jì)算布局
5> 歷數(shù)據(jù)內(nèi)容,根據(jù)索引取出對(duì)應(yīng)的attributes(使用layoutAttributesForCellWithIndexPath),根據(jù)九宮格算法設(shè)置布局
6> 節(jié)1: 實(shí)時(shí)布局,重寫shouldInvalidateLayoutForBoundsChange(bounds改變重新布局,scrollview的contentoffset>bounds)
7> 細(xì)節(jié)2: 計(jì)算設(shè)置itemsize(保證內(nèi)容顯示完整,uicollectionview的content size是根據(jù)itemize計(jì)算的),根據(jù)列最大高度/對(duì)應(yīng)列數(shù)量求出,最大高度累加得到
8> 細(xì)節(jié)3: 追加item到最短列,避免底部參差不齊.
<h1>21席赂、UIImage有哪幾種加載方式</h1>
二進(jìn)制 imageWithData
Bundle imageWithName
本地路徑 imageWithContentOfFile
<h1>22吮铭、描述九宮格算法</h1>
NSInteger col = x;//定義列數(shù)
NSInteger index = self.shopsView.subviews.count;//獲取下標(biāo)
CGFloat margin = (self.shopsView.frame.size.width - col*viewW) / (col - 1);//定義間隔
CGFloat viewX = (index % col ) * (viewW + margin);
CGFloat viewY = (index / col ) * (viewH + 10);
<h1>23、實(shí)現(xiàn)圖片輪播圖</h1>
1> ScrollView只需要設(shè)置三個(gè)ImageView即可颅停,并且默認(rèn)顯示中間的ImageView
2> 根據(jù)ScrollView的移動(dòng)情況谓晌,迅速變化三個(gè)ImageView中圖片數(shù)據(jù)
3> ImageView更新完畢后,偷偷把ScrollView拉回到中間的ImageView位置癞揉,這樣視覺(jué)效果上就實(shí)現(xiàn)了無(wú)限循環(huán)的效果
<h1>24纸肉、應(yīng)用的生命周期</h1>
-(BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions 告訴代理進(jìn)程啟動(dòng)但還沒(méi)進(jìn)入狀態(tài)保存
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 告訴代理啟動(dòng)基本完成程序準(zhǔn)備開(kāi)始運(yùn)行
-(void)applicationWillResignActive:(UIApplication *)application 當(dāng)應(yīng)用程序?qū)⒁敕腔顒?dòng)狀態(tài)執(zhí)行,在此期間喊熟,應(yīng)用程序不接收消息或事件柏肪,比如來(lái)電話了
-(void)applicationDidBecomeActive:(UIApplication *)application 當(dāng)應(yīng)用程序入活動(dòng)狀態(tài)執(zhí)行,這個(gè)剛好跟上面那個(gè)方法相反
-(void)applicationDidEnterBackground:(UIApplication *)application 當(dāng)程序被推送到后臺(tái)的時(shí)候調(diào)用芥牌。所以要設(shè)置后臺(tái)繼續(xù)運(yùn)行烦味,則在這個(gè)函數(shù)里面設(shè)置即可
-(void)applicationWillEnterForeground:(UIApplication *)application 當(dāng)程序從后臺(tái)將要重新回到前臺(tái)時(shí)候調(diào)用,這個(gè)剛好跟上面的那個(gè)方法相反壁拉。
-(void)applicationWillTerminate:(UIApplication *)application 當(dāng)程序?qū)⒁顺鍪潜徽{(diào)用谬俄,通常是用來(lái)保存數(shù)據(jù)和一些退出前的清理工作岩遗。
<h1>25、load initialize方法的區(qū)別</h1>
+(void)load;
當(dāng)類對(duì)象被引入項(xiàng)目時(shí), runtime 會(huì)向每一個(gè)類對(duì)象發(fā)送 load 消息
load 方法會(huì)在每一個(gè)類甚至分類被引入時(shí)僅調(diào)用一次,調(diào)用的順序:父類優(yōu)先于子類, 子類優(yōu)先于分類
load 方法不會(huì)被類自動(dòng)繼承
+(void)initialize;
也是在第一次使用這個(gè)類的時(shí)候會(huì)調(diào)用這個(gè)方法
<h1>26凤瘦、UIScrollView 大概是如何實(shí)現(xiàn)的,它是如何捕捉案铺、響應(yīng)手勢(shì)的蔬芥?</h1>
我對(duì)UIScrollView的理解是frame就是他的contentSize,bounds就是他的可視范圍,通過(guò)改變bounds從而達(dá)到讓用戶誤以為在滾動(dòng),以下是一個(gè)簡(jiǎn)單的UIScrollView實(shí)現(xiàn)
第二個(gè)問(wèn)題個(gè)人理解是解決手勢(shì)沖突,對(duì)自己添加的手勢(shì)進(jìn)行捕獲和響應(yīng)
// 讓UIScrollView遵守UIGestureRecognizerDelegate協(xié)議,實(shí)現(xiàn)這個(gè)方法,在這里方法里對(duì)添加的手勢(shì)進(jìn)行處理就可以解決沖突
(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
<h1>27、+[UIView animateWithDuration:animations:completion:] 內(nèi)部大概是如何實(shí)現(xiàn)的控汉?</h1>
animateWithDuration:這就等于創(chuàng)建一個(gè)定時(shí)器
animations:這是創(chuàng)建定時(shí)器需要實(shí)現(xiàn)的SEL
completion:是定時(shí)器結(jié)束以后的一個(gè)回調(diào)block
<h1>28笔诵、什么時(shí)候會(huì)發(fā)生「隱式動(dòng)畫」?</h1>
當(dāng)改變CALayer的一個(gè)可做動(dòng)畫的屬性姑子,它并不能立刻在屏幕上體現(xiàn)出來(lái).相反乎婿,它是從先前的值平滑過(guò)渡到新的值。這一切都是默認(rèn)的行為街佑,你不需要做額外的操作,這就是隱式動(dòng)畫
<h1>29谢翎、如何把一張大圖縮小為1/4大小的縮略圖?</h1>
imgData = UIImageJPEGRepresentation(image, 0.6f)
<h1>30沐旨、當(dāng)TableView的Cell改變時(shí)森逮,如何讓這些改變以動(dòng)畫的形式呈現(xiàn)?</h1>
[tableView deselectRowAtIndexPath:indexPath animated:TRUE];
// 重點(diǎn)是這2句代碼實(shí)現(xiàn)的功能
[tableView beginUpdates];
[tableView endUpdates];
<h1>31磁携、為什么當(dāng) Core Animation 完成時(shí)褒侧,layer 又會(huì)恢復(fù)到原先的狀態(tài)?</h1>
因?yàn)檫@些產(chǎn)生的動(dòng)畫只是假象,并沒(méi)有對(duì)layer進(jìn)行改變.那么為什么會(huì)這樣呢,這里要講一下圖層樹(shù)里的呈現(xiàn)樹(shù).呈現(xiàn)樹(shù)實(shí)際上是模型圖層的復(fù)制,但是它的屬性值表示了當(dāng)前外觀效果,動(dòng)畫的過(guò)程實(shí)際上只是修改了呈現(xiàn)樹(shù),并沒(méi)有對(duì)圖層的屬性進(jìn)行改變,所以在動(dòng)畫結(jié)束以后圖層會(huì)恢復(fù)到原先狀態(tài)
<h1>32谊迄、設(shè)計(jì)一個(gè)進(jìn)度條闷供。</h1>
1> 自定義一個(gè)UIView的子類
//提供一個(gè)成員屬性,接收下載進(jìn)度值
@property (nonatomic, assign) CGFloat progress;
2> 重寫成員屬性progress的setter
//每次改變成員屬性progress的值统诺,就會(huì)調(diào)用它的setter
-(void)setProgress:(CGFloat)progress
{
_progress = progress;
//當(dāng)下載進(jìn)度改變時(shí)歪脏,手動(dòng)調(diào)用重繪方法
[self setNeedsDisplay];
}
3> 重寫
-(void)drawRect:(CGRect)rect(核心)
-(void)drawRect:(CGRect)rect
{
//設(shè)置圓弧的半徑
CGFloat radius = rect.size.width * 0.5;
//設(shè)置圓弧的圓心
CGPoint center = CGPointMake(radius, radius);
//設(shè)置圓弧的開(kāi)始的角度(弧度制)
CGFloat startAngle = - M_PI_2;
//設(shè)置圓弧的終止角度
CGFloat endAngle = - M_PI_2 + 2 * M_PI * self.progress;
//使用UIBezierPath類繪制圓弧
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius - 5 startAngle:startAngle endAngle:endAngle clockwise:YES];
//將繪制的圓弧渲染到圖層上(即顯示出來(lái))
[path stroke];
}
<h1>33、如何播放 GIF 圖片粮呢,有什么優(yōu)化方案么唾糯?</h1>
UIImageView用來(lái)顯示圖片, 使用UIImageView中的動(dòng)畫數(shù)組來(lái)實(shí)現(xiàn)圖片的動(dòng)畫效果
用UIWebView來(lái)顯示動(dòng)態(tài)圖片
第三方顯示框架
通過(guò)UIImageView顯示動(dòng)畫效果鬼贱,實(shí)際上是把動(dòng)態(tài)的圖拆成了一組靜態(tài)的圖移怯,放到數(shù)組中,播放的時(shí)候依次從數(shù)組中取出这难。如果播放的圖片比較少占得內(nèi)存比較小或者比較常用(比如工具條上一直顯示的動(dòng)態(tài)小圖標(biāo))舟误,可以選擇用imageNamed:方式獲取圖片,但是通過(guò)這種方式加到內(nèi)存中姻乓,使用結(jié)束,不會(huì)自己釋放场斑,多次播放動(dòng)畫會(huì)造成內(nèi)存溢出問(wèn)題诚亚。因此,對(duì)于大圖或經(jīng)常更換的圖学少,在取圖片的時(shí)候可以選擇imageWithContentsOfFile:方式獲取圖片,優(yōu)化內(nèi)存秧骑。
使用UIWebView顯示圖片需要注意顯示圖片的尺寸與UIWebView尺寸的設(shè)置版确,如果只是為了顯示動(dòng)態(tài)圖片,可以禁止UIWebView滾動(dòng)乎折。在顯示動(dòng)態(tài)圖片的時(shí)候绒疗,即使是動(dòng)圖的背景處為透明,默認(rèn)顯示出來(lái)是白色背景骂澄,這個(gè)時(shí)候需要手動(dòng)設(shè)置UIWebView的透明才能達(dá)到顯示動(dòng)圖背景透明的效果吓蘑。
<h1>34、應(yīng)用程序的啟動(dòng)流程坟冲?</h1>
1.執(zhí)行Main
2.執(zhí)行UIApplicationMain函數(shù).
3.創(chuàng)建UIApplication對(duì)象,并設(shè)置UIApplicationMain對(duì)象的代理.
UIApplication的第三個(gè)參數(shù)就是UIApplication的名稱,如果指定為nil,它會(huì)默認(rèn)為UIApplication.
UIApplication的第四個(gè)參數(shù)為UIApplication的代理.
4.開(kāi)啟一個(gè)主運(yùn)行循環(huán).保證應(yīng)用程序不退出.
5.加載info.plist.加載配置文件.判斷一下info.plist文件當(dāng)中有沒(méi)有Main storyboard file base name里面有沒(méi)有指定storyboard文件,
如果有就去加載info.plist文件,如果沒(méi)有,那么應(yīng)用程序加載完畢.
<h1>35磨镶、控制器View的加載過(guò)程?</h1>
當(dāng)程序訪問(wèn)了控制器的View屬性時(shí)會(huì)先判斷控制器的View是否存在健提,如果存在就直接返回已經(jīng)存在的View棋嘲;
如果不存在,就會(huì)先調(diào)用loadView這個(gè)方法矩桂;如果控制器的loadView方法實(shí)現(xiàn)了沸移,就會(huì)按照l(shuí)oadView方法加載自定義的View;
如果控制器的loadView方法沒(méi)有實(shí)現(xiàn)就會(huì)判斷storyboard是否存在侄榴;
如果storyboard存在就會(huì)按照storyboard加載控制器的View雹锣;如果storyboard不存在,就會(huì)創(chuàng)建一個(gè)空視圖返回癞蚕。
<h1>36蕊爵、事件傳遞與響應(yīng)的完整過(guò)程?</h1>
在產(chǎn)生一個(gè)事件時(shí),系統(tǒng)會(huì)將該事件加入到一個(gè)由UIApplication管理的事件隊(duì)列中,
UIApplication會(huì)從事件隊(duì)列中取出最前面的事件,將它傳遞給先發(fā)送事件給應(yīng)用程序的主窗口.
主窗口會(huì)調(diào)用hitTest方法尋找最適合的視圖控件,找到后就會(huì)調(diào)用視圖控件的touches方法來(lái)做具體的事情.
當(dāng)調(diào)用touches方法,它的默認(rèn)做法, 就會(huì)將事件順著響應(yīng)者鏈條往上傳遞,
傳遞給上一個(gè)響應(yīng)者,接著就會(huì)調(diào)用上一個(gè)響應(yīng)者的touches方法
<h1>37桦山、下列回調(diào)機(jī)制的理解不正確的是</h1>
A target-action:當(dāng)兩個(gè)對(duì)象之間有?較緊密的關(guān)系時(shí)攒射,如視圖控制器與其下的某個(gè)視圖。
B delegate:當(dāng)某個(gè)對(duì)象收到多個(gè)事件恒水,并要求同一個(gè)對(duì)象來(lái)處理所有事件時(shí)会放。委托機(jī)制必須依賴于某個(gè)協(xié)議定義的?法來(lái)發(fā)送消息。
C NSNotification:當(dāng)需要多個(gè)對(duì)象或兩個(gè)無(wú)關(guān)對(duì)象處理同一個(gè)事件時(shí)钉凌。
D Block:適?于回調(diào)只發(fā)?生一次的簡(jiǎn)單任務(wù)咧最。
參考答案:B
<h1>38、給UIImageView添加圓角</h1>
最直接的方法就是使用如下屬性設(shè)置:
imgView.layer.cornerRadius = 10;
// 這一行代碼是很消耗性能的
imgView.clipsToBounds = YES;
好處是使用簡(jiǎn)單,操作方便矢沿。壞處是離屏渲染(off-screen-rendering)需要消耗性能滥搭。對(duì)于圖片比較多的視圖上,不建議使用這種方法來(lái)設(shè)置圓角捣鲸。通常來(lái)說(shuō)瑟匆,計(jì)算機(jī)系統(tǒng)中CPU、GPU栽惶、顯示器是協(xié)同工作的愁溜。CPU計(jì)算好顯示內(nèi)容提交到GPU,GPU渲染完成后將渲染結(jié)果放入幀緩沖區(qū)媒役。
簡(jiǎn)單來(lái)說(shuō),離屏渲染宪迟,導(dǎo)致本該GPU干的活酣衷,結(jié)果交給了CPU來(lái)干,而CPU又不擅長(zhǎng)GPU干的活次泽,于是拖慢了UI層的FPS(數(shù)據(jù)幀率)穿仪,并且離屏需要?jiǎng)?chuàng)建新的緩沖區(qū)和上下文切換,因此消耗較大的性能意荤。
給UIImage添加生成圓角圖片的擴(kuò)展API:
- (UIImage *)hyb_imageWithCornerRadius:(CGFloat)radius {
CGRect rect = (CGRect){0.f, 0.f, self.size};
UIGraphicsBeginImageContextWithOptions(self.size, NO, UIScreen.mainScreen.scale);
CGContextAddPath(UIGraphicsGetCurrentContext(),
[UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius].CGPath);
CGContextClip(UIGraphicsGetCurrentContext());
[self drawInRect:rect];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
然后調(diào)用時(shí)就直接傳一個(gè)圓角來(lái)處理:
imgView.image = [[UIImage imageNamed:@"test"] hyb_imageWithCornerRadius:4];
這么做就是on-screen-rendering了啊片,通過(guò)模擬器->debug->Color Off-screen-rendering看到?jīng)]有離屏渲染了!(黃色的小圓角沒(méi)有顯示了,說(shuō)明這個(gè)不是離屏渲染了)
在畫之前先通過(guò)UIBezierPath添加裁剪玖像,但是這種不實(shí)用
- (void)drawRect:(CGRect)rect {
CGRect bounds = self.bounds;
[[UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:8.0] addClip];
[self.image drawInRect:bounds];
}
通過(guò)mask遮罩實(shí)現(xiàn)
<h1>39紫谷、一個(gè)view已經(jīng)初始化完畢,view上面添加了n個(gè)button(可能使用循環(huán)創(chuàng)建)捐寥,除用view的tag之外笤昨,還可以采用什么辦法來(lái)找到自己想要的button來(lái)修改Button的值</h1>
這個(gè)問(wèn)題有很多種方式,而且不同的使用場(chǎng)景也不一樣的握恳。比如說(shuō):
? 第一種:如果是點(diǎn)擊某個(gè)按鈕后瞒窒,才會(huì)刷新它的值,其它不用修改乡洼,
那么不用引用任何按鈕崇裁,直接在回調(diào)時(shí),就已經(jīng)將接收響應(yīng)的按鈕給傳過(guò)來(lái)了束昵,直接通過(guò)它修改即可拔稳。
? 第二種:點(diǎn)擊某個(gè)按鈕后,所有與之同類型的按鈕都要修改值锹雏,
那么可以通過(guò)在創(chuàng)建按鈕時(shí)將按鈕存入到數(shù)組中壳炎,在需要的時(shí)候遍歷查找。
<h1>40、使用drawRect有什么影響匿辩?</h1>
drawRect方法依賴Core Graphics框架來(lái)進(jìn)行自定義的繪制腰耙,但這種方法主要的缺點(diǎn)就是它處理touch事件的方式:每次按鈕被點(diǎn)擊后,都會(huì)用setNeddsDisplay進(jìn)行強(qiáng)制重繪铲球;而且不止一次挺庞,每次單點(diǎn)事件觸發(fā)兩次執(zhí)行。這樣的話從性能的角度來(lái)說(shuō)稼病,對(duì)CPU和內(nèi)存來(lái)說(shuō)都是欠佳的选侨。特別是如果在我們的界面上有多個(gè)這樣的UIButton實(shí)例。
<h1>41然走、viewWillLayoutSubView你總是知道的援制。</h1>
ontroller layout觸發(fā)的時(shí)候,開(kāi)發(fā)者有機(jī)會(huì)去重新layout自己的各個(gè)subview芍瑞。
橫豎屏切換的時(shí)候晨仑,系統(tǒng)會(huì)響應(yīng)一些函數(shù),其中 viewWillLayoutSubviews 和 viewDidLayoutSubviews拆檬。
- (void)viewWillLayoutSubviews {
[self _shouldRotateToOrientation:(UIDeviceOrientation)[UIApplication sharedApplication].statusBarOrientation];
}
-(void)_shouldRotateToOrientation:(UIDeviceOrientation)orientation {
if (orientation == UIDeviceOrientationPortrait ||orientation == UIDeviceOrientationPortraitUpsideDown) {
// 豎屏
} else {
// 橫屏
}
}
通過(guò)上述一個(gè)函數(shù)就知道橫豎屏切換的接口了洪己。
注意:viewWillLayoutSubviews只能用在ViewController里面,在view里面沒(méi)有響應(yīng)竟贯。
<h1>42答捕、一個(gè)tableView是否可以關(guān)聯(lián)兩個(gè)不同的數(shù)據(jù)源?</h1>
當(dāng)然是可以關(guān)聯(lián)多個(gè)不同的數(shù)據(jù)源屑那,但是不能同時(shí)使用多個(gè)數(shù)據(jù)源而已拱镐。比如,一個(gè)列表有兩個(gè)篩選功能持际,一個(gè)是篩選城市痢站,一個(gè)是篩選時(shí)間,那么這兩個(gè)就是兩個(gè)數(shù)據(jù)源了选酗。當(dāng)篩選城市時(shí)阵难,就會(huì)使用城市數(shù)據(jù)源;當(dāng)篩選時(shí)間時(shí)芒填,就會(huì)使用時(shí)間數(shù)據(jù)源呜叫。
<h1>43、如何自動(dòng)計(jì)算cell的高度殿衰?</h1>
實(shí)現(xiàn)原理:通過(guò)數(shù)據(jù)模型的id作為key朱庆,以確保唯一,如何才能保證復(fù)用cell時(shí)不會(huì)出現(xiàn)混亂闷祥。在配置完數(shù)據(jù)后娱颊,通過(guò)更新約束傲诵,得到最后一個(gè)控件的frame,就只可以判斷cell實(shí)際需要的高度箱硕,并且緩存下來(lái)拴竹,下次再獲取時(shí),判斷是否存在剧罩,若存在則直接返回栓拜。因此,只會(huì)計(jì)算一遍
<h1>44惠昔、UITableView是如何計(jì)算內(nèi)容高度的幕与?為什么初始化時(shí)配置數(shù)據(jù)時(shí),獲取行高的代理方法會(huì)調(diào)用數(shù)據(jù)條數(shù)次镇防?</h1>
UITableView是繼承于UIScrollView的啦鸣,因此也有contentSize。要得到tableview的contentsize来氧,就需要得到所有cell的高度诫给,從而計(jì)算出總高度,才能得到contentsize饲漾。因此蝙搔,在reloadData時(shí)缕溉,就會(huì)調(diào)用該代理方法數(shù)據(jù)條數(shù)次考传。
<h1>45、一個(gè)tableView是否可以關(guān)聯(lián)兩個(gè)不同的數(shù)據(jù)源?你會(huì)怎么處理?</h1>
答:首先我們從代碼來(lái)看证鸥,數(shù)據(jù)源如何關(guān)聯(lián)上的僚楞,其實(shí)是在數(shù)據(jù)源關(guān)聯(lián)的代理方法里實(shí)現(xiàn)的。
因此我們并不關(guān)心如何去關(guān)聯(lián)他枉层,他怎么關(guān)聯(lián)上泉褐,方法只是讓我返回根據(jù)自己的需要去設(shè)置如相關(guān)的數(shù)據(jù)源。
因此鸟蜡,我覺(jué)得可以設(shè)置多個(gè)數(shù)據(jù)源啊膜赃,但是有個(gè)問(wèn)題是,你這是想干嘛呢?想讓列表如何顯示揉忘,不同的數(shù)據(jù)源分區(qū)塊顯示?
<h1>46跳座、給出委托方法的實(shí)例,并且說(shuō)出UITableVIew的Data Source方法</h1>
CocoaTouch框架中用到了大量委托泣矛,其中UITableViewDelegate就是委托機(jī)制的典型應(yīng)用疲眷,是一個(gè)典型的使用委托來(lái)實(shí)現(xiàn)適配器模式。
其中UITableViewDelegate協(xié)議是目標(biāo)您朽,tableview是適配器狂丝,實(shí)現(xiàn)UITableViewDelegate協(xié)議,并將自身設(shè)置為talbeview的delegate的對(duì)象,是被適配器几颜,一般情況下該對(duì)象是UITableViewController倍试。
UITableVIew的Data Source方法有:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
<h1>47、cocoa touch框架</h1>
答:iPhone OS 應(yīng)用程序的基礎(chǔ) Cocoa Touch 框架重用了許多 Mac 系統(tǒng)的成熟模式菠剩,但是它更多地專注于觸摸的接口和優(yōu)化易猫。
UIKit 為您提供了在 iPhone OS 上實(shí)現(xiàn)圖形,事件驅(qū)動(dòng)程序的基本工具具壮,其建立在和 Mac OS X 中一樣的 Foundation 框架上准颓,包括文件處理,網(wǎng)絡(luò)棺妓,字符串操作等攘已。
Cocoa Touch 具有和 iPhone 用戶接口一致的特殊設(shè)計(jì)。有了 UIKit怜跑,您可以使用 iPhone OS 上的獨(dú)特的圖形接口控件样勃,按鈕,以及全屏視圖的功能性芬,您還可以使用加速儀和多點(diǎn)觸摸手勢(shì)來(lái)控制您的應(yīng)用峡眶。
各色俱全的框架 除了UIKit 外,Cocoa Touch 包含了創(chuàng)建世界一流 iPhone 應(yīng)用程序需要的所有框架植锉,從三維圖形辫樱,到專業(yè)音效,甚至提供設(shè)備訪問(wèn) API 以控制攝像頭俊庇,或通過(guò) GPS 獲知當(dāng)前位置狮暑。
Cocoa Touch 既包含只需要幾行代碼就可以完成全部任務(wù)的強(qiáng)大的 Objective-C 框架,也在需要時(shí)提供基礎(chǔ)的 C 語(yǔ)言 API 來(lái)直接訪問(wèn)系統(tǒng)辉饱。這些框架包括:
Core Animation:通過(guò) Core Animation搬男,您就可以通過(guò)一個(gè)基于組合獨(dú)立圖層的簡(jiǎn)單的編程模型來(lái)創(chuàng)建豐富的用戶體驗(yàn)。
Core Audio:Core Audio 是播放彭沼,處理和錄制音頻的專業(yè)技術(shù)缔逛,能夠輕松為您的應(yīng)用程序添加強(qiáng)大的音頻功能。
Core Data:提供了一個(gè)面向?qū)ο蟮臄?shù)據(jù)管理解決方案姓惑,它易于使用和理解褐奴,甚至可處理任何應(yīng)用或大或小的數(shù)據(jù)模型。
功能列表:框架分類
下面是 Cocoa Touch 中一小部分可用的框架:
音頻和視頻:Core Audio 挺益,OpenAL 歉糜,Media Library ,AV Foundation
數(shù)據(jù)管理 :Core Data 望众,SQLite
圖形和動(dòng)畫 :Core Animation 匪补,OpenGL ES 伞辛,Quartz 2D
網(wǎng)絡(luò):Bonjour ,WebKit 夯缺,BSD Sockets
用戶應(yīng)用:Address Book 蚤氏,Core Location ,Map Kit 踊兜,Store Kit
<h1>48竿滨、xib文件的構(gòu)成分為哪3個(gè)圖標(biāo)?都具有什么功能捏境。</h1>
File’s Owner 是所有 nib 文件中的每個(gè)圖標(biāo)于游,它表示從磁盤加載 nib 文件的對(duì)象;
First Responder 就是用戶當(dāng)前正在與之交互的對(duì)象垫言;
View 顯示用戶界面贰剥;完成用戶交互;是 UIView 類或其子類筷频。
<h1>49蚌成、簡(jiǎn)述應(yīng)用程序按Home鍵進(jìn)入后臺(tái)時(shí)的生命周期,和從后臺(tái)回到前臺(tái)時(shí)的生命周期? 應(yīng)用程序:</h1>
-[AppDelegate application:willFinishLaunchingWithOptions:]-[AppDelegate application:didFinishLaunchingWithOptions:]-[AppDelegate applicationDidBecomeActive:]
退到后臺(tái):
-[AppDelegate applicationWillResignActive:]
-[AppDelegate applicationDidEnterBackground:]
回到前臺(tái):
-[AppDelegate applicationWillEnterForeground:]
-[AppDelegate applicationDidBecomeActive:]
ViewController之間,
加載頁(yè)面:
-[mainViewController viewDidLoad]
-[mainViewController viewWillAppear:]
-[mainViewController viewWillLayoutSubviews]
-[mainViewController viewDidLayoutSubviews]
-[mainViewController viewDidAppear:]
退出當(dāng)前頁(yè)面:
-[mainViewController viewWillDisappear:]
-[mainViewController viewDidDisappear:]
返回之前頁(yè)面:
-[mainViewController viewWillAppear:]
-[mainViewController viewWillLayoutSubviews]
-[mainViewController viewDidLayoutSubviews]
-[mainViewController viewDidAppear:]
<h1>50凛捏、是否使用Core Text或者Core Image等担忧?如果使用過(guò),請(qǐng)談?wù)勀闶褂肅ore Text或者Core Image的體驗(yàn)坯癣。</h1>
CoreText
? 隨意修改文本的樣式
? 圖文混排(純C語(yǔ)言)
? 國(guó)外:Niumb
Core Image(濾鏡處理)
* 能調(diào)節(jié)圖片的各種屬性(對(duì)比度, 色溫, 色差等)
<h1>51瓶盛、你做iphone開(kāi)發(fā)時(shí)候,有哪些傳值方式,view和view之間是如何傳值的?</h1>
block, target-action ,代理,屬性
<h1>52、有哪幾種手勢(shì)通知方法坡锡、寫清楚方法名蓬网?</h1>
-(void)touchesBegan:(NSSet*)touchedwithEvent:(UIEvent*)event;
-(void)touchesMoved:(NSSet*)touched withEvent:(UIEvent*)event;
-(void)touchesEnded:(NSSet*)touchedwithEvent:(UIEvent*)event;
-(void)touchesCanceled:(NSSet*)touchedwithEvent:(UIEvent*)event;