第一篇:黑馬程序員:IOS面試寶典之關(guān)于動(dòng)畫(huà)
關(guān)于動(dòng)畫(huà)
1.談?wù)勀銓?duì)Core Graphic 繪圖的了解? CoreGraphics也稱(chēng)為Quartz 2D 是UIKit下的主要繪圖系統(tǒng),頻繁的用于繪制自定義視圖。Core Graphics是高度集成于UIView和其他UIKit部分的。Core Graphics數(shù)據(jù)結(jié)構(gòu)和函數(shù)可以通過(guò)前綴CG來(lái)識(shí)別。
視圖可以通過(guò)子視圖、圖層或?qū)崿F(xiàn)drawRect:方法來(lái)表現(xiàn)內(nèi)容,如果說(shuō)實(shí)現(xiàn)了drawRect:方法,那么最好就不要混用其他方法了,如圖層和子視圖。自定義繪圖大部分是由UIKit或者Core Graphics來(lái)實(shí)現(xiàn)的。
2D繪圖一般可以拆分成以下幾個(gè)操作: 線條 , 路徑 , 文本 , 圖片 , 漸變 由于像素是依賴(lài)于目標(biāo)的,所以2D繪圖并不能操作單獨(dú)的像素,我們可以從上下文(Context)讀取它。
繪圖就好比在畫(huà)布上拿著畫(huà)筆機(jī)械的進(jìn)行畫(huà)畫(huà),通過(guò)制定不同的參數(shù)來(lái)進(jìn)行不同的繪制。
http://004km.cn/articles/jIJzMf
http://blog.csdn.net/mangosnow/article/details/37054765
2.Core Animation(核心動(dòng)畫(huà))? CoreAnimation也就是核心動(dòng)畫(huà), 是一組非常強(qiáng)大的動(dòng)畫(huà)處理API, 可以使用少量的代碼做出絢麗的效果, 是直接作用在CALayer上的, 并非UIView, 并且Core Animation的動(dòng)畫(huà)執(zhí)行過(guò)程都是在后臺(tái)操作, 不會(huì)阻塞主線程.所有動(dòng)畫(huà)都是作用在CALayer上的, 當(dāng)把動(dòng)畫(huà)添加到Layer上, 是不直接修改它的屬性, Core Animation維護(hù)了兩個(gè)平行l(wèi)ayer的層次結(jié)構(gòu), 模型層樹(shù)可以看到Layer的狀態(tài), 表示層樹(shù)則是動(dòng)畫(huà)正在表現(xiàn)的值的近似.Core Animation的使用步驟: 1> 使用它需要先添加QuartzCore.framework框架和引入主頭文件
3>.通過(guò)調(diào)用CALayer的addAnimation:forKey:方法增加CAAnimation對(duì)象到CALayer中,這樣就能開(kāi)始執(zhí)行動(dòng)畫(huà)了
4>.通過(guò)調(diào)用CALayer的removeAnimationForKey:方法可以停止CALayer中的動(dòng)畫(huà)
1.轉(zhuǎn)場(chǎng)動(dòng)畫(huà)? CATransition-轉(zhuǎn)場(chǎng)動(dòng)畫(huà), 作為CAAnimation的子類(lèi),用于做轉(zhuǎn)場(chǎng)動(dòng)畫(huà),能夠?yàn)閷犹峁┮瞥銎聊缓鸵迫肫聊坏膭?dòng)畫(huà)效果。iOS比Mac OS X的轉(zhuǎn)場(chǎng)動(dòng)畫(huà)效果少一點(diǎn).UINavigationController就是通過(guò)CATransition實(shí)現(xiàn)了將控制器的視圖推入屏幕的動(dòng)畫(huà)效果.如下是轉(zhuǎn)場(chǎng)動(dòng)畫(huà)的過(guò)渡效果:
使用UIView的動(dòng)畫(huà)函數(shù), 實(shí)現(xiàn)轉(zhuǎn)場(chǎng)動(dòng)畫(huà) 1> 單視圖:
+(void)transitionWithView:(UIView*)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options
animations:(void(^)(void))animations completion:(void(^)(BOOL finished))completion;參數(shù)說(shuō)明:
duration:動(dòng)畫(huà)的持續(xù)時(shí)間 view:需要進(jìn)行轉(zhuǎn)場(chǎng)動(dòng)畫(huà)的視圖 options:轉(zhuǎn)場(chǎng)動(dòng)畫(huà)的類(lèi)型
animations:將改變視圖屬性的代碼放在這個(gè)block中 completion:動(dòng)畫(huà)結(jié)束后,會(huì)自動(dòng)調(diào)用這個(gè)block 2> 雙視圖: +(void)transitionFromView:(UIView*)fromView toView:(UIView*)toView
duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options finished))completion;參數(shù)說(shuō)明:
duration:動(dòng)畫(huà)的持續(xù)時(shí)間 options:轉(zhuǎn)場(chǎng)動(dòng)畫(huà)的類(lèi)型
animations:將改變視圖屬性的代碼放在這個(gè)block中 completion:動(dòng)畫(huà)結(jié)束后,會(huì)自動(dòng)調(diào)用這個(gè)block
completion:(void
(^)(BOOL 2.一個(gè)動(dòng)畫(huà)怎么實(shí)現(xiàn)? 以轉(zhuǎn)場(chǎng)動(dòng)畫(huà)為例: 1> 創(chuàng)建CATransition對(duì)象
CATransition *animation = [CATransition animation];2> 設(shè)置運(yùn)動(dòng)時(shí)間(即動(dòng)畫(huà)時(shí)間)animation.duration = DURATION;3> 設(shè)置運(yùn)動(dòng)type(類(lèi)型)
animation.type = type;if(subtype!= nil){ 4> 設(shè)置子類(lèi)(和type配合使用, 指定運(yùn)動(dòng)的方向)animation.subtype = subtype;} 5> 設(shè)置運(yùn)動(dòng)速度(動(dòng)畫(huà)的運(yùn)動(dòng)軌跡,用于變化起點(diǎn)和終點(diǎn)之間的插值計(jì)算,形象點(diǎn)說(shuō)它決定了動(dòng)畫(huà)運(yùn)行的節(jié)奏,比如是均勻變化(相同時(shí)間變化量相同)還是先快后慢,先慢后快還是先慢再快再慢)animation.timingFunction = UIViewAnimationOptionCurveEaseInOut;
6> 將動(dòng)畫(huà)添加到view的Layer層
[view.layer addAnimation:animation forKey:@“animation”];動(dòng)畫(huà)類(lèi)型如下: typedef enum : NSUInteger { Fade = 1, //淡入淡出 Push, //推擠 Reveal, //揭開(kāi) MoveIn, //覆蓋 Cube, //立方體 SuckEffect, //吮吸 OglFlip, //翻轉(zhuǎn) RippleEffect, //波紋
PageCurl, //翻頁(yè) PageUnCurl, //反翻頁(yè) CameraIrisHollowOpen, //開(kāi)鏡頭 CameraIrisHollowClose, //關(guān)鏡頭 CurlDown, //下翻頁(yè) CurlUp, //上翻頁(yè) FlipFromLeft, //左翻轉(zhuǎn) FlipFromRight, //右翻轉(zhuǎn) } AnimationType;3.CADisplayLink CADisplayLink是一種以屏幕刷新頻率觸發(fā)的時(shí)鐘機(jī)制,每秒鐘執(zhí)行大約60次左右
CADisplayLink是一個(gè)計(jì)時(shí)器,可以使繪圖代碼與視圖的刷新頻率保持同步,而NSTimer無(wú)法確保計(jì)時(shí)器實(shí)際被觸發(fā)的準(zhǔn)確時(shí)間 使用方法:
定義CADisplayLink并制定觸發(fā)調(diào)用方法 將顯示鏈接添加到主運(yùn)行循環(huán)隊(duì)列
第二篇:黑馬程序員:IOS面試寶典之OC語(yǔ)言
OC語(yǔ)言(★★)
有人可能會(huì)問(wèn)對(duì)于我們學(xué)iOS的同學(xué)來(lái)講,面試還會(huì)問(wèn)Objective-C基礎(chǔ)嗎?答案是會(huì)的,但是不會(huì)太多,因此我給了兩顆星的重要程度。一般筆試的時(shí)候出現(xiàn)Objective-C基礎(chǔ)題的概率比較大,口頭面試的時(shí)候比較少,比如自己在面試的時(shí)候一些對(duì)基礎(chǔ)知識(shí)比較看重的面試官會(huì)深究著Objective-C基礎(chǔ)去問(wèn),比如Objective-C內(nèi)存管理等等。
一、Objective-C語(yǔ)法
1.面向?qū)ο蠖加心男┨匦砸约澳銓?duì)這些特性的理解
繼承:繼承是從已有類(lèi)得到繼承信息創(chuàng)建新類(lèi)的過(guò)程。提供繼承信息的類(lèi)被稱(chēng)為父類(lèi)(超類(lèi)、基類(lèi));得到繼承信息的類(lèi)被稱(chēng)為子類(lèi)(派生類(lèi))。繼承讓變化中的軟件系統(tǒng)有了一定的延續(xù)性,同時(shí)繼承也是封裝程序中可變因素的重要手段。
封裝:通常認(rèn)為封裝是把數(shù)據(jù)和操作數(shù)據(jù)的方法綁定起來(lái),對(duì)數(shù)據(jù)的訪問(wèn)只能通過(guò)已定義的接口。面向?qū)ο蟮谋举|(zhì)就是將現(xiàn)實(shí)世界描繪成一系列完全自治、封閉的對(duì)象。我們?cè)陬?lèi)中編寫(xiě)的方法就是對(duì)實(shí)現(xiàn)細(xì)節(jié)的一種封裝;我們編寫(xiě)一個(gè)類(lèi)就是對(duì)數(shù)據(jù)和數(shù)據(jù)操作的封裝??梢哉f(shuō),封裝就是隱藏一切可隱藏的東西,只向外界提供最簡(jiǎn)單的編程接口。
多態(tài)性:多態(tài)性是指允許不同子類(lèi)型的對(duì)象對(duì)同一消息作出不同的響應(yīng)。簡(jiǎn)單的說(shuō)就是用同樣的對(duì)象引用調(diào)用同樣的方法但是做了不同的事情。多態(tài)性分為編譯時(shí)的多態(tài)性和運(yùn)行時(shí)的多態(tài)性。如果將對(duì)象的方法視為對(duì)象向外界提供的服務(wù),那么運(yùn)行時(shí)的多態(tài)性可以解釋為:當(dāng)A系統(tǒng)訪問(wèn)B系統(tǒng)提供的服務(wù)時(shí),B系統(tǒng)有多種提供服務(wù)的方式,但一切對(duì)A
系統(tǒng)來(lái)說(shuō)都是透明的。方法重載(overload)實(shí)現(xiàn)的是編譯時(shí)的多態(tài)性(也稱(chēng)為前綁定),而方法重寫(xiě)(override)實(shí)現(xiàn)的是運(yùn)行時(shí)的多態(tài)性(也稱(chēng)為后綁定)。運(yùn)行時(shí)的多態(tài)是面向?qū)ο笞罹璧臇|西,要實(shí)現(xiàn)多態(tài)需要做兩件事:1.方法重寫(xiě)(子類(lèi)繼承父類(lèi)并重寫(xiě)父類(lèi)中已有的或抽象的方法);2.對(duì)象造型(用父類(lèi)型引用引用子類(lèi)型對(duì)象,這樣同樣的引用調(diào)用同樣的方法就會(huì)根據(jù)子類(lèi)對(duì)象的不同而表現(xiàn)出不同的行為)。
抽象:抽象是將一類(lèi)對(duì)象的共同特征總結(jié)出來(lái)構(gòu)造類(lèi)的過(guò)程,包括數(shù)據(jù)抽象和行為抽象兩方面。抽象只關(guān)注對(duì)象有哪些屬性和行為,并不關(guān)注這些行為的細(xì)節(jié)是什么。
2.我們說(shuō)的Objective-C是動(dòng)態(tài)運(yùn)行時(shí)語(yǔ)言是什么意思?(When we call objective c is runtime language what does it mean?)主要是將數(shù)據(jù)類(lèi)型的確定由編譯時(shí),推遲到了運(yùn)行時(shí)。這個(gè)問(wèn)題其實(shí)淺涉及到兩個(gè)概念,運(yùn)行時(shí)和多態(tài)。簡(jiǎn)單來(lái)說(shuō), 運(yùn)行時(shí)機(jī)制使我們直到運(yùn)行時(shí)才去決定一個(gè)對(duì)象的類(lèi)別,以及調(diào)用該類(lèi)別對(duì)象指定方法。多態(tài):不同對(duì)象以自己的方式響應(yīng)相同的消息的能力叫做多態(tài)。意思就是假設(shè)生物類(lèi)(life)都用有一個(gè)相同的方法-eat;那人類(lèi)屬于生物,豬也屬于生物,都繼承了life后,實(shí)現(xiàn)各自的eat,但是調(diào)用是我們只需調(diào)用各自的eat方法。也就是不同的對(duì)象以自己的方式響應(yīng)了相同的消息(響應(yīng)了eat這個(gè)選擇器)。因此也可以說(shuō),運(yùn)行時(shí)機(jī)制是多態(tài)的基礎(chǔ).3.readwrite,readonly, assign,retain,copy,nonatomic, strong, weak屬性的作用?并區(qū)別strong(強(qiáng)引用)、weak(弱引用)?什么情況使用copy,assign和retain? readwrite 是可讀可寫(xiě)特性;需要生成getter方法和setter方法時(shí);
readonly 是只讀特性只會(huì)生成getter方法不會(huì)生成setter方法,不希望屬性在類(lèi)外改變;
assign 是賦值特性,setter方法將傳入?yún)?shù)賦值給實(shí)例變量;僅設(shè)置變量時(shí);, assign用于簡(jiǎn)單數(shù)據(jù)類(lèi)型,如NSInteger,double,bool;retain 表示持有特性,setter方法將傳入?yún)?shù)先保留,再賦值,傳入?yún)?shù)的retaincount會(huì)+1;
copy 表示賦值特性,setter方法將傳入對(duì)象復(fù)制一份;需要完全一份新的變量時(shí);nonatomic 非原子操作,決定編譯器生成的setter getter是否是原子操作;atomic表示多線程安全,一般使用nonatomic。
retain 和copy用戶(hù)對(duì)象,copy用于當(dāng) a指向一個(gè)對(duì)象, b也想指向同樣的對(duì)象的時(shí)候,如果用assign,a如果釋放,再調(diào)用b會(huì)crash,如果用copy 的方式,a和b各自有自己的內(nèi)存,就可以解決這個(gè)問(wèn)題。retain 會(huì)使計(jì)數(shù)器加1,也可以解決assign的問(wèn)題。另外:atomic和nonatomic用來(lái)決定編譯器生成的getter和setter是否為原子操作。在多線程環(huán)境下,原子操作是必要的,否則有可能引起錯(cuò)誤的結(jié)果。
其實(shí)從這個(gè)也可以引申到內(nèi)存管理的一系列問(wèn)題.面試官會(huì)讓你講講MRC和ARC的理解,隨即也引申出Block的內(nèi)存機(jī)制,為啥推薦Block用copy,Block會(huì)存在哪些內(nèi)存問(wèn)題?循環(huán)引用?
4.分別描述內(nèi)存管理要點(diǎn)、autorelease、release、NSAutoreleasePool?并說(shuō)明autorelease是什么時(shí)候被release的?簡(jiǎn)述什么時(shí)候由你負(fù)責(zé)釋放對(duì)象,什么時(shí)候不由你釋放?[NSAutoreleasePool release]和[NSAutoreleasePool drain]有什么區(qū)別? 內(nèi)存管理要點(diǎn): Objective-C 使用引用計(jì)數(shù)機(jī)制(retainCount)來(lái)管理內(nèi)存。內(nèi)存每被引用一次,該內(nèi)存的引用計(jì)數(shù)+1,每被釋放一次引用計(jì)數(shù)-1。當(dāng)引用計(jì)數(shù) = 0 的時(shí)候,調(diào)用該對(duì)象的 dealloc 方法,來(lái)徹底從內(nèi)存中刪除該對(duì)象。alloc,allocWithZone,new(帶初始化)時(shí):該對(duì)象引用計(jì)數(shù) +1;
retain:手動(dòng)為該對(duì)象引用計(jì)數(shù) +1;copy:對(duì)象引用計(jì)數(shù) +1;
mutableCopy:生成一個(gè)新對(duì)象,新對(duì)象引用計(jì)數(shù)為 1;release:手動(dòng)為該對(duì)象引用計(jì)數(shù)-1;
autorelease:把該對(duì)象放入自動(dòng)釋放池,當(dāng)自動(dòng)釋放池釋放時(shí),其內(nèi)的對(duì)象引用計(jì)數(shù)-1。
NSAutoreleasePool: NSAutoreleasePool是通過(guò)接收對(duì)象向它發(fā)送的autorelease消息,記錄該對(duì)象的release消息,當(dāng)自動(dòng)釋放池被銷(xiāo)毀時(shí),會(huì)自動(dòng)向池中的對(duì)象發(fā)送release消息。autorelease 是在自動(dòng)釋放池被銷(xiāo)毀,向池中的對(duì)象發(fā)送release只能釋放自己擁有的對(duì)象, 區(qū)別是:在引用計(jì)數(shù)環(huán)境下(在不使用ARC情況下),兩者基本一樣,在GC(垃圾回收制)環(huán)境下,release 是一個(gè)no-op(無(wú)效操作),所以無(wú)論是不是GC都使用drain
面試中內(nèi)存管理,release和autorelease的含義?這里尤其要強(qiáng)調(diào)下autorelease,它引申出自動(dòng)釋放池,也能引申出Run loop!5.自動(dòng)釋放池是什么,如何工作 ? 當(dāng) 您向一個(gè)對(duì)象發(fā)送一個(gè)autorelease消息時(shí),Cocoa就會(huì)將該對(duì)象的一個(gè)引用放入到最新的自動(dòng)釋放池。它仍然是個(gè)對(duì)象,因此自動(dòng)釋放池定義的作用域內(nèi)的其它對(duì)象可以向它發(fā)送消息。當(dāng)程序執(zhí)行到作用域結(jié)束的位置時(shí),自動(dòng)釋放池就會(huì)被釋放,池中的所有對(duì)象也就被釋放。
1>.Objective-C 是 通過(guò)一種“referring counting”(引用計(jì)數(shù))的方式來(lái)管理內(nèi)存的, 對(duì)象在開(kāi)始分配內(nèi)存(alloc)的時(shí)候引用計(jì)數(shù)為1,以后每當(dāng)碰到有copy,retain的時(shí)候引用計(jì)數(shù)都會(huì)加1, 每當(dāng)碰到release和autorelease的時(shí)候引用計(jì)數(shù)就會(huì)減1,如果此對(duì)象的計(jì)數(shù)變?yōu)榱?, 就會(huì)被系統(tǒng)銷(xiāo)毀.2>.NSAutoreleasePool 就是用來(lái)做引用計(jì)數(shù)的管理工作的,這個(gè)東西一般不用自己管理.3>.autorelease和release沒(méi)什么區(qū)別,只是引用計(jì)數(shù)減1的時(shí)機(jī)不同而已,autorelease會(huì)在對(duì)象的使用真正結(jié)束的時(shí)候才做引用計(jì)數(shù)減1.6.IPhone OS有沒(méi)有垃圾回收?autorelease 和垃圾回收制(gc)有什么關(guān)系? IPhone OS 中沒(méi)有垃圾回收。autorelease只是延遲釋放,gc是每隔一段時(shí)間詢(xún)問(wèn)程序,看是否有無(wú)指針指向的對(duì)象,若有,就將它回收。他們兩者沒(méi)有什么關(guān)系。
7.簡(jiǎn)述NotificationCenter、KVC、KVO、Delegate?并說(shuō)明它們之間的區(qū)別? KVO(Key-Value-Observing):是鍵值監(jiān)聽(tīng),鍵值觀察機(jī)制,當(dāng)觀察者為一個(gè)對(duì)象的屬性進(jìn)行了注冊(cè),被觀察對(duì)象的isa指針被修改的時(shí)候,isa指針就會(huì)指向一個(gè)中間類(lèi),而不是真實(shí)的類(lèi)。所以 isa指針其實(shí)不需要指向?qū)嵗龑?duì)象真實(shí)的類(lèi)。所以我們的程序最好不要依賴(lài)于isa指針。在調(diào)用類(lèi)的方法的時(shí)候,最好要明確對(duì)象實(shí)例的類(lèi)名
KVC(Key-Value-Coding)內(nèi)部的實(shí)現(xiàn):是鍵值編碼,一個(gè)對(duì)象在調(diào)用setValue的時(shí)候,(1)首先根據(jù)方法名找到運(yùn)行方法的時(shí)候所需要的環(huán) 境參數(shù)。(2)他會(huì)從自己isa指針結(jié)合環(huán)境參數(shù),找到具體的方法實(shí)現(xiàn)的接口。(3)再直接查找得來(lái)的具體的方法實(shí)現(xiàn)。Delegate:代理的目的是改變或傳遞控制鏈。允許一個(gè)類(lèi)在某些特定時(shí)刻通知到其他類(lèi),而不需要獲取到那些類(lèi)的指針??梢詼p少框架復(fù)雜度。消息的發(fā)送者(sender)告知接收者(receiver)某個(gè)事件將要發(fā)生,delegate同意然然后發(fā)送者響應(yīng)事件,delegate機(jī)制使得接收者可以改變發(fā)送者的行為。通常發(fā)送者和接收者的關(guān)系是直接的一對(duì)多的關(guān)系。
Notification:消息的發(fā)送者告知接收者事件已經(jīng)發(fā)生或者將要發(fā)送,僅此而已,接收者并不能反過(guò)來(lái)影響發(fā)送者的行為。通常發(fā)送者和接收者的關(guān)系是間接的多對(duì)多關(guān)系。
1).效率肯定是delegate比nsnotification高。
2).delegate方法比notification更加直接,最典型的特征是,delegate方法往往需要關(guān)注返回值,也就是delegate方法的結(jié)果。比如-windowShouldClose:,需要關(guān)心返回的是yes還是no。所以delegate方法往往包含should這個(gè)很傳神的詞。也就是好比你做我的delegate,我會(huì)問(wèn)你我想關(guān)閉窗口你愿意嗎?你需要給我一個(gè)答案,我根據(jù)你的答案來(lái)決定如何做下一步。相反的,notification最大的特色就是不關(guān)心接受者的態(tài)度,我只管
把通告放出來(lái),你接受不接受就是你的事情,同時(shí)我也不關(guān)心結(jié)果。所以notification往往用did這個(gè)詞匯,比如NSWindowDidResizeNotification,那么nswindow對(duì)象放出這個(gè)notification后就什么都不管了也不會(huì)等待接受者的反應(yīng)。
1)兩個(gè)模塊之間聯(lián)系不是很緊密,就用notification傳值,例如多線程之間傳值用notificaiton。
2)delegate只是一種較為簡(jiǎn)單的回調(diào),且主要用在一個(gè)模塊中,例如底層功能完成了,需要把一些值傳到上層去,就事先把上層的函數(shù)通過(guò)delegate傳到底層,然后在底層call這個(gè)delegate,它們都在一個(gè)模塊中,完成一個(gè)功能,例如說(shuō) NavgationController 從 B 界面到A 點(diǎn)返回按鈕(調(diào)用popViewController方法)可以用delegate比較好。
What is lazy loading? 就是懶漢模式,只在用到的時(shí)候才去初始化。也可以理解成延時(shí)加載。我覺(jué)得最好也最簡(jiǎn)單的一個(gè)列子就是tableView中圖片的加載顯示了。一個(gè)延時(shí)載,避免內(nèi)存過(guò)高,一個(gè)異步加載,避免線程堵塞。
9.OC有多繼承嗎?沒(méi)有的話可以用什么方法替代? 多繼承即一個(gè)子類(lèi)可以有多個(gè)父類(lèi),它繼承了多個(gè)父類(lèi)的特性。Object-c的類(lèi)沒(méi)有多繼承,只支持單繼承,如果要實(shí)現(xiàn)多繼承的話,可以通過(guò)類(lèi)別和協(xié)議的方式來(lái)實(shí)現(xiàn),OC類(lèi)似于多繼承,是在用protocol委托代理來(lái)實(shí)現(xiàn)的;可以實(shí)現(xiàn)多個(gè)接口,通過(guò)實(shí)現(xiàn)多個(gè)接口可以完成C++的多重繼承;Category是類(lèi)別,一般情況用分類(lèi)好,用Category去重寫(xiě)類(lèi)的方法,僅對(duì)本Category有效,不會(huì)影響到其他類(lèi)與原有類(lèi)的關(guān)系。
10.分別描述類(lèi)別(categories)和延展(extensions)是什么?以及兩者的區(qū)別?繼承和類(lèi)別在實(shí)現(xiàn)中有何區(qū)別?為什么Category只能為對(duì)象添加方法,卻不能添加成員變量? 類(lèi)別:在沒(méi)有原類(lèi).m文件的基礎(chǔ)上,給該類(lèi)添加方法;
延展:一種特殊形式的類(lèi)別,主要在一個(gè)類(lèi)的.m文件里聲明和實(shí)現(xiàn)延展的作用,就是給某類(lèi)添加私有方法或是私有變量。兩個(gè)的區(qū)別:延展可以添加屬性并且它添加的方法是必須要實(shí)現(xiàn)的。延展可以認(rèn)為是一個(gè)私有的類(lèi)目。
繼承和類(lèi)別在實(shí)現(xiàn)中的區(qū)別:類(lèi)別可以在不獲悉,不改變?cè)瓉?lái)代碼的情況下往里面添加新的方法,只能添加,不能刪除修改。并且如果類(lèi)別和原來(lái)類(lèi)中的方法產(chǎn)生名稱(chēng)沖突,則類(lèi)別將覆蓋原來(lái)的方法,因?yàn)轭?lèi)別具有更高的優(yōu)先級(jí)。Category只能為對(duì)象添加方法,卻不能添加成員變量的原因:如果可以添加成員變量,添加的成員變量沒(méi)有辦法初始化
11.Objective-C有私有方法么?私有變量呢?如多沒(méi)有的話,有沒(méi)有什么代替的方法? objective-c類(lèi)里面的方法只有兩種, 靜態(tài)方法和實(shí)例方法.但是可以通過(guò)把方法的聲明和定義都放在.m文件中來(lái)實(shí)現(xiàn)一個(gè)表面上的私有方法。有私有變量,可以通過(guò)@private來(lái)修飾,或者把聲明放到.m文件中。在Objective‐C中,所有實(shí)例變量默認(rèn)都是私有的,所有實(shí)例方法默認(rèn)都是公有的
12.#include與#import的區(qū)別? #import與@class的區(qū)別? #import指令是Object-C針對(duì)#include的改進(jìn)版本,#import確保引用的文件只會(huì)被引用一次,這樣你就不會(huì)陷入遞歸包含的問(wèn)題中。
#import與@class二者的區(qū)別在于:
1>#import會(huì)鏈入該頭文件的全部信息,包括實(shí)體變量和方法等;而@class只是告訴編譯器,其后面聲明的名稱(chēng)是類(lèi)的名稱(chēng),至于這些類(lèi)是如何定義的,暫時(shí)不用考慮。
2>在頭文件中,一般只需要知道被引用的類(lèi)的名稱(chēng)就可以了。不需要知道其內(nèi)部的實(shí)體變量和方法,所以在頭文件中一般使用@class來(lái)聲明這個(gè)名稱(chēng)是類(lèi)的名稱(chēng)。而在實(shí)現(xiàn)類(lèi)里面,因?yàn)闀?huì)用到這個(gè)引用類(lèi)的內(nèi)部的實(shí)體變量和方法,所以需要使用#import來(lái)包含這個(gè)被引用類(lèi)的頭文件。
3>在編譯效率方面考慮,如果你有100個(gè)頭文件都#import了同一個(gè)頭文件,或者這些文件是依次引用的,如A–>B, B–>C, C–>D這樣的引用關(guān)系。當(dāng)最開(kāi)始的那個(gè)頭文件有變化的話,后面所有引用它的類(lèi)都需要重新編譯,如果你的類(lèi)有很多的話,這將耗費(fèi)大量的時(shí)間。而是用@class則不會(huì)。
4>如果有循環(huán)依賴(lài)關(guān)系,如:A–>B, B–>A這樣的相互依賴(lài)關(guān)系,如果使用#import來(lái)相互包含,那么就會(huì)出現(xiàn)編譯錯(cuò)誤,如果使用@class在兩個(gè)類(lèi)的頭文件中相互聲明,則不會(huì)有編譯錯(cuò)誤出現(xiàn)。所以,一般來(lái)說(shuō),@class是放在interface中的,只是為了在interface中引用這個(gè)類(lèi),把這個(gè)類(lèi)作為一個(gè)類(lèi)型來(lái)用的。在實(shí)現(xiàn)這個(gè)接口的實(shí)現(xiàn)類(lèi)中,如果需要引用這個(gè)類(lèi)的實(shí)體變量或者方法之類(lèi)的,還是需要import在@class中聲明的類(lèi)進(jìn)來(lái).13.淺復(fù)制和深復(fù)制的區(qū)別?(Difference between shallow copy and deep copy?)淺層復(fù)制(copy):只復(fù)制指向?qū)ο蟮闹羔?,而不?fù)制引用對(duì)象本身。意思就是說(shuō)我有個(gè)A對(duì)象,復(fù)制一份后得到A_copy對(duì)象后,對(duì)于淺復(fù)制來(lái)說(shuō),A和A_copy指向的是同一個(gè)內(nèi)存資源,復(fù)制的只不過(guò)是是一個(gè)指針,對(duì)象本身資源還是只有一份,那如果我們對(duì)A_copy執(zhí)行了修改操作,那么發(fā)現(xiàn)A引用的對(duì)象同樣被修改,這其實(shí)違背了我們復(fù)制拷貝的一個(gè)思想。
深層復(fù)制(mutableCopy):復(fù)制引用對(duì)象本身。深復(fù)制就好理解了,內(nèi)存中存在了兩份獨(dú)立對(duì)象本身,當(dāng)修改A時(shí),A_copy不變。
用網(wǎng)上一哥們通俗的話將就是:
淺復(fù)制好比你和你的影子,你完蛋,你的影子也完蛋
深復(fù)制好比你和你的克隆人,你完蛋,你的克隆人還活著。
14.類(lèi)變量的@protected,@private,@public,@package聲明各有什么含義? 變量的作用域不同,@protected 該類(lèi)和所有子類(lèi)中的方法可以直接訪問(wèn)這樣的變量,這是默認(rèn)的;@private 該類(lèi)中的方法可以訪問(wèn)這樣的變量,子類(lèi)不可以;@public除了自己和子類(lèi)方法外,也可以被其他類(lèi)或者其他模塊中的方法訪問(wèn);@package 目前尚未得出結(jié)論.15.static 關(guān)鍵字的作用? 1>函數(shù)體內(nèi) static 變量的作用范圍為該函數(shù)體,不同于 auto 變量,該變量的內(nèi)存只被分配一次,因此其值在下次調(diào)用時(shí)仍維持上次的值;
2>在模塊內(nèi)的 static 全局變量可以被模塊內(nèi)所用函數(shù)訪問(wèn),但不能被模塊外其它函數(shù)訪問(wèn);
3>在模塊內(nèi)的 static 函數(shù)只可被這一模塊內(nèi)的其它函數(shù)調(diào)用,這個(gè)函數(shù)的使用范圍被限制在聲明 它的模塊內(nèi);
4>在類(lèi)中的 static 成員變量屬于整個(gè)類(lèi)所擁有,對(duì)類(lèi)的所有對(duì)象只有一份拷貝;
5>在類(lèi)中的 static 成員函數(shù)屬于整個(gè)類(lèi)所擁有,這個(gè)函數(shù)不接收 this 指針,因而只能訪問(wèn)類(lèi)的static 成員變量
16.關(guān)鍵字volatile有什么含意?并給出三個(gè)不同的例子
一個(gè)定義為volatile的變量是說(shuō)這變量可能會(huì)被意想不到地改變,這樣,編譯器就不會(huì)去假設(shè)這個(gè)變量的值了。精確地說(shuō)就是,優(yōu)化器在用到這個(gè)變量時(shí)必須每次都小心地重新讀取這個(gè)變量的值,而不是使用保存在寄存器里的備份。下面是volatile變量的幾個(gè)例子:
? 并行設(shè)備的硬件寄存器(如:狀態(tài)寄存器)
? 一個(gè)中斷服務(wù)子程序中會(huì)訪問(wèn)到的非自動(dòng)變量(Non-automatic variables)? 多線程應(yīng)用中被幾個(gè)任務(wù)共享的變量
17.Objective-C與C、C+++之間的聯(lián)系和區(qū)別?
Objective-C和C++都是C的面向?qū)ο蟮某?/p>
Object與C++的區(qū)別主要點(diǎn):Objective-C是完全動(dòng)態(tài)的,支持在運(yùn)行時(shí)動(dòng)態(tài)類(lèi)型決議(dynamic typing),動(dòng)態(tài)綁定(dynamic binding)以及動(dòng)態(tài)裝載(dynamic loading);而C++是部分動(dòng)態(tài)的,編譯時(shí)靜態(tài)綁定,通過(guò)嵌入類(lèi)(多重繼承)和虛函數(shù)(虛表)來(lái)模擬實(shí)現(xiàn)。
Objective-C 在語(yǔ)言層次上支持動(dòng)態(tài)消息轉(zhuǎn)發(fā),其消息發(fā)送語(yǔ)法為 [object function];而且C++ 為 object->function()。兩者的語(yǔ)義也不同,在 Objective-C 里是說(shuō)發(fā)送消息到一個(gè)對(duì)象上,至于這個(gè)對(duì)象能不能響應(yīng)消息以及是響應(yīng)還是轉(zhuǎn)發(fā)消息都不會(huì) crash;而在 C++ 里是說(shuō)對(duì)象進(jìn)行了某個(gè)操作,如果對(duì)象沒(méi)有這個(gè)操作的話,要么編譯會(huì)報(bào)錯(cuò)(靜態(tài)綁定),要么程序會(huì) crash 掉的(動(dòng)態(tài)綁定)。
18.目標(biāo)-動(dòng)作機(jī)制
目標(biāo)是動(dòng)作消息的接收者。一個(gè)控件,或者更為常見(jiàn)的是它的單元,以插座變量(參見(jiàn)“插座變量”部分)的形式保有其動(dòng)作消息的目標(biāo)。
動(dòng)作是控件發(fā)送給目標(biāo)的消息,或者從目標(biāo)的角度看,它是目標(biāo)為了響應(yīng)動(dòng)作而實(shí)現(xiàn)的方法.程序需要某些機(jī)制來(lái)進(jìn)行事件和指令的翻譯。這個(gè)機(jī)制就是目標(biāo)-動(dòng)作機(jī)制。
19.動(dòng)態(tài)綁定
在運(yùn)行時(shí)確定要調(diào)用的方法 , 動(dòng)態(tài)綁定將調(diào)用方法的確定也推遲到運(yùn)行時(shí)。在編譯時(shí),方法的調(diào)用并不和代碼綁定在一起,只有在消實(shí)發(fā)送出來(lái)之后,才確定被調(diào)用的代碼。通過(guò)
動(dòng)態(tài)類(lèi)型和動(dòng)態(tài)綁 定技術(shù),代碼每次執(zhí)行都可以得到不同的結(jié)果。運(yùn)行時(shí)因子負(fù)責(zé)確定消息的接收者和被調(diào)用的方法。運(yùn)行時(shí)的消息分發(fā)機(jī)制為動(dòng)態(tài)綁定提供支持。當(dāng)向一個(gè)動(dòng)態(tài)類(lèi)型確定了的對(duì)象發(fā)送消息時(shí),運(yùn)行環(huán)境系統(tǒng)會(huì)通過(guò)接收者的isa指針定位對(duì)象的類(lèi),并以此為起點(diǎn)確定被調(diào)用的方法,方法和消息是動(dòng)態(tài)綁定的。而且,不必在Objective-C 代碼中做任何工作,就可以自動(dòng)獲取動(dòng)態(tài)綁定的好處。在每次發(fā)送消息時(shí),特別是當(dāng)消息的接收者是動(dòng)態(tài)類(lèi)型已經(jīng)確定的對(duì)象時(shí),動(dòng)態(tài)綁定就會(huì)例行而透明地發(fā)生
20.iPad開(kāi)發(fā)與iPhone開(kāi)發(fā)有什么不同?
開(kāi)發(fā)iPad和iPhone應(yīng)用使用的是相同的SDK,它們之間的區(qū)別主要體現(xiàn)在設(shè)備硬件和UI操作上。
(1)設(shè)備硬件:由于iPad不具備電話功能,iPad1也沒(méi)有相機(jī),所以相關(guān)的特性如電話、SMS等無(wú)法使用。
(2)UI操作:由于iPad屏幕大小為9.7英寸,而iPhone的屏幕是3.5英寸,這就決定了兩者操作方式的不同。有些控件,如UIPopoverController, UISliptViewController 只能在iPad中使用,而不能在iPhone中使用;而且當(dāng)需要presentModalViewController時(shí),Window presentation style 只對(duì)iPad有效;除此之外,iPad產(chǎn)品開(kāi)發(fā)中還需針對(duì)iPad大屏幕考慮加入多指手勢(shì)以增加用戶(hù)體驗(yàn)
21.換膚技術(shù)使用了什么技術(shù)? 22.談?wù)勀銓?duì)runtime的了解? 23.算法和數(shù)據(jù)結(jié)構(gòu)
第三篇:黑馬程序員:IOS面試寶典之c語(yǔ)言
黑馬程序員:IOS面試寶典之c語(yǔ)言
C語(yǔ)言語(yǔ)法
1.局部變量能否和全局變量重名?
答:能,局部會(huì)屏蔽全局。要用全局變量,需要使用“::”;局部變量可以與全局變量同名,在函數(shù)內(nèi)引用這個(gè)變量時(shí),會(huì)用到同名的局部變量,而不會(huì)用到全局變量。對(duì)于有些編譯器而言,在同一個(gè)函數(shù)內(nèi)可以定義多個(gè)同 名的局部變量,比如在兩個(gè)循環(huán)體內(nèi)都定義一個(gè)同名的局部變量,而那個(gè)局部變量的作用域就在那個(gè)循環(huán)體內(nèi)。
2.如何引用一個(gè)已經(jīng)定義過(guò)的全局變量?
答:extern 可以用引用頭文件的方式,也可以用extern關(guān)鍵字,如果用引用頭文件方式來(lái)引用某個(gè)在頭文件中聲明的全局變理,假定你將那個(gè)編寫(xiě)錯(cuò)了,那么在編譯期 間會(huì)報(bào)錯(cuò),如果你用extern方式引用時(shí),假定你犯了同樣的錯(cuò)誤,那么在編譯期間不會(huì)報(bào)錯(cuò),而在連接期間報(bào)錯(cuò)。
3.全局變量可不可以定義在可被多個(gè).C文件包含的頭文件中?為什么?
答:可以,在不同的C文件中以static形式來(lái)聲明同名全局變量。
可以在不同的C文件中聲明同名的全局變量,前提是其中只能有一個(gè)C文件中對(duì)此變量賦初值,此時(shí)連接不會(huì)出錯(cuò).4.關(guān)鍵字volatile有什么含意?并舉出三個(gè)不同的例子?
一個(gè)定義為volatile的變量是說(shuō)這變量可能會(huì)被意想不到地改變,這樣,編譯器就不會(huì)去假設(shè)這個(gè)變量的值了。精確地說(shuō)就是,優(yōu)化器在用到這個(gè)變量時(shí)必須每次都小心地重新讀取這個(gè)變量的值,而不是使用保存在寄存器里的備份。下面是volatile變量的幾個(gè)例子:
1)并行設(shè)備的硬件寄存器(如:狀態(tài)寄存器)
2)一個(gè)中斷服務(wù)子程序中會(huì)訪問(wèn)到的非自動(dòng)變量(Non-automatic variables)3)多線程應(yīng)用中被幾個(gè)任務(wù)共享的變量
5.static 關(guān)鍵字的作用是什么?
(1)函數(shù)體內(nèi) static 變量的作用范圍為該函數(shù)體,不同于 auto 變量,該變量的內(nèi)存只被分配一次,因此其值在下次調(diào)用時(shí)仍維持上次的值;
(2)在模塊內(nèi)的 static 全局變量可以被模塊內(nèi)所用函數(shù)訪問(wèn),但不能被模塊外其它函數(shù)訪問(wèn);
(3)在模塊內(nèi)的 static 函數(shù)只可被這一模塊內(nèi)的其它函數(shù)調(diào)用,這個(gè)函數(shù)的使用范圍被限制在聲明
它的模塊內(nèi);
(4)在類(lèi)中的 static 成員變量屬于整個(gè)類(lèi)所擁有,對(duì)類(lèi)的所有對(duì)象只有一份拷貝;
(5)在類(lèi)中的 static 成員函數(shù)屬于整個(gè)類(lèi)所擁有,這個(gè)函數(shù)不接收 this 指針,因而只能訪問(wèn)類(lèi)的static 成員變量。
6.堆和棧的區(qū)別是什么?
管理方式:對(duì)于棧來(lái)講,是由編譯器自動(dòng)管理,無(wú)需我們手工控制;對(duì)于堆來(lái)說(shuō),釋放工作由程序員控制,容易產(chǎn)生memory leak。
申請(qǐng)大?。簵#涸赪indows下,棧是向低地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu),是一塊連續(xù)的內(nèi)存的區(qū)域。這句話的意思是棧頂?shù)牡刂泛蜅5淖畲笕萘渴窍到y(tǒng) 預(yù)先規(guī)定好的,在WINDOWS下,棧的大小是2M(也有的說(shuō)是1M,總之是一個(gè)編譯時(shí)就確定的常數(shù)),如果申請(qǐng)的空間超過(guò)棧的剩余空間時(shí),將提示 overflow。因此,能從棧獲得的空間較小。堆:堆是向高地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu),是不連續(xù)的內(nèi)存區(qū)域。這是由于系統(tǒng)是用鏈表來(lái)存儲(chǔ)的空閑內(nèi)存地 址的,自然是不連續(xù)的,而鏈表的遍歷方向是由低地址向高地址。堆的大小受限于計(jì)算機(jī)系統(tǒng)中有效的虛擬內(nèi)存。由此可見(jiàn),堆獲得的空間比較靈活,也比較大。
碎片問(wèn)題:對(duì)于堆來(lái)講,頻繁的new/delete勢(shì)必會(huì)造成內(nèi)存空間的不連續(xù),從而造成大量的碎片,使程序效率降低。對(duì)于棧來(lái)講,則不會(huì)存在這個(gè) 問(wèn)題,因?yàn)闂J窍冗M(jìn)后出的隊(duì)列,他們是如此的一一對(duì)應(yīng),以至于永遠(yuǎn)都不可能有一個(gè)內(nèi)存塊從棧中間彈出 分配方式:堆都是動(dòng)態(tài)分配的,沒(méi)有靜態(tài)分配的堆。棧有2種分配方式:靜態(tài)分配和動(dòng)態(tài)分配。靜態(tài)分配是編譯器完成的,比如局部變量的分配。動(dòng)態(tài)分配由 alloca函數(shù)進(jìn)行分配,但是棧的動(dòng)態(tài)分配和堆是不同的,他的動(dòng)態(tài)分配是由編譯器進(jìn)行釋放,無(wú)需我們手工實(shí)現(xiàn)。
分配效率:棧是機(jī)器系統(tǒng)提供的數(shù)據(jù)結(jié)構(gòu),計(jì)算機(jī)會(huì)在底層對(duì)棧提供支持:分配專(zhuān)門(mén)的寄存器存放棧的地址,壓棧出棧都有專(zhuān)門(mén)的指令執(zhí)行,這就決定了棧的 效率比較高。堆則是C/C++函數(shù)庫(kù)提供的,它的機(jī)制是很復(fù)雜的
7.static全局變量與普通的全局變量有什么區(qū)別?static局部變量和普通局部變量有什么區(qū)別?static函數(shù)與普通函數(shù)有什么區(qū)別?
答: 1)全局變量(外部變量)的說(shuō)明之前再冠以static 就構(gòu)成了靜態(tài)的全局變量。全局變量本身就是靜態(tài)存儲(chǔ)方式,靜態(tài)全局變量當(dāng)然也是靜態(tài)存儲(chǔ)方式。這兩者在存儲(chǔ)方式上并無(wú)不同。這兩者的區(qū)別在于非靜態(tài)全局變量的作用域是整個(gè)源程序,當(dāng)一個(gè)源程序由多個(gè)源文件組成時(shí),非靜態(tài)的全局變量在各個(gè)源文件中都是有效的。而靜態(tài)全局變量則限制了其作用域,即只在定義該變量的源文件內(nèi)有效,在同一源程序的其它源文件中不能使用它。由于靜態(tài)全局變量的作用域局限于一個(gè)源文件內(nèi),只能為該源文件內(nèi)的函數(shù)公用,因此可以避免在其它源文件中引起錯(cuò)誤。
2)從以上分析可以看出,把局部變量改變?yōu)殪o態(tài)變量后是改變了它的存儲(chǔ)方式即改變了它的生存期。把全局變量改變?yōu)殪o態(tài)變量后是改變了它的作用域,限制了它的使用范圍。
3)static函數(shù)與普通函數(shù)作用域不同,僅在本文件。只在當(dāng)前源文件中使用的函數(shù)應(yīng)該說(shuō)明為內(nèi)部函數(shù)(static),內(nèi)部函數(shù)應(yīng)該在當(dāng)前源文件中說(shuō)明和定義。對(duì)于可在當(dāng)前源文件以外使用的函數(shù),應(yīng)該在一個(gè)頭文件中說(shuō)明,要使用這些函數(shù)的源文件要包含這個(gè)頭文件
綜上所述: static全局變量與普通的全局變量有什么區(qū)別:
static全局變量只初使化一次,防止在其他文件單元中被引用;
static局部變量和普通局部變量有什么區(qū)別:
static局部變量只被初始化一次,下一次依據(jù)上一次結(jié)果值;
static函數(shù)與普通函數(shù)有什么區(qū)別:
static函數(shù)在內(nèi)存中只有一份,普通函數(shù)在每個(gè)被調(diào)用中維持一份拷貝
8.關(guān)鍵字const的作用分別是什么?
const int a;int const a;const int *a;int const *a;int * const a;int const * const a;1> 前兩個(gè)的作用是一樣:a 是一個(gè)常整型數(shù)
2> 第三、四個(gè)意味著 a 是一個(gè)指向常整型數(shù)的指針(整型數(shù)是不可修改的,但指針可以)3> 第五個(gè)的意思:a 是一個(gè)指向整型數(shù)的常指針(指針指向的整型數(shù)是可以修改的,但指針是不可修改的)4> 最后一個(gè)意味著:a 是一個(gè)指向常整型數(shù)的常指針(指針指向的整型數(shù)是不可修改的,同時(shí)指針也是不可修改的)9.struct與union的區(qū)別是什么?
設(shè)有以下說(shuō)明和定義:
typedef union
{ long i;int k[5];char c;} DATE;
struct data { int cat;DATE cow;double dog;} too;
DATE max;
則語(yǔ)句 printf(“%d”,sizeof(struct data)+sizeof(max));的執(zhí)行結(jié)果是:___52____ 考點(diǎn):區(qū)別struct與union.(一般假定在32位機(jī)器上)
答:DATE是一個(gè)union, 變量公用空間.里面最大的變量類(lèi)型是int[5], 占用20個(gè)字節(jié).所以它的大小是20.data是一個(gè)struct, 每個(gè)變量分開(kāi)占用空間.依次為int4 + DATE20 + double8 = 32.所以結(jié)果是 20 + 32 = 52.當(dāng)然...在某些16位編輯器下, int可能是2字節(jié),那么結(jié)果是 int2 + DATE10 + double8 = 20 10.關(guān)于指針的理解
1.請(qǐng)寫(xiě)出下題輸出結(jié)果:
1.Main(){ 2.Int a[5] = {1,2,3,4,5};
3.Int *ptr =(int *)(&a+1);4.Printf(“%d,%d”,*(a+1),*(ptr – 1));5.} 答:2,5
*(a+1)就是a[1],*(ptr-1)就是a[4],執(zhí)行結(jié)果是2.5,&a+1不是首地址+1,系統(tǒng)會(huì)認(rèn)為加一個(gè)a數(shù)組的偏 移,是偏移了一個(gè)數(shù)組的大?。ū纠?個(gè)int,int *ptr=(int *)(&a+1);則ptr實(shí)際 是&(a[5]),也就是a+5原因如下:
&a是數(shù)組指針,其類(lèi)型為 int(*)[5];而指針加1要根據(jù)指針類(lèi)型加上一定的值,不同類(lèi)型的指針+1之后增加的大小不同。a是長(zhǎng)度為5的int數(shù)組指針,所以要加 5*sizeof(int)所以ptr實(shí)際是a[5],但是prt與(&a+1)類(lèi)型是不一樣的(這點(diǎn)很重要),所以prt-1只會(huì)減去sizeof(int*),a,&a的地址是一樣的,但意思不一樣,a是數(shù)組首地址,也就是a[0]的地址,&a是對(duì)象(數(shù)組)首地址,a+1是數(shù)組下一元素的地址,即a[1],&a+1是下一個(gè)對(duì)象的地址,即a[5].2.寫(xiě)出下列代碼的輸出內(nèi)容
#include
int inc(int a)
{ return(++a);}
int multi(int*a,int*b,int*c)
{
return(*c=*a**b);}
typedef int(FUNC1)(int in);
typedef int(FUNC2)(int*,int*,int*);
void show(FUNC2 fun,int arg1, int*arg2)
{
FUNC1 p=&inc;
int temp =p(arg1);
fun(&temp,&arg1, arg2);
printf(“%dn”,*arg2);
}
main()
{
int a;
//局部變量a為0;
show(multi,10,&a);
return 0;
}
答:110
3.以下為Windows NT下的32位C++程序,請(qǐng)計(jì)算sizeof的值void Func(char str[100]){
sizeof(str)= ? } void *p = malloc(100);sizeof(p)= ? 答案:這題 很常見(jiàn)了,Func(char str[100])函數(shù)中數(shù)組名作為函數(shù)形參時(shí),在函數(shù)體內(nèi),數(shù)組名失去了本身的內(nèi)涵,僅僅只是一個(gè)指針;在失去其內(nèi)涵的同時(shí),它還失去了其常量特性,可以作自增、自減等 操作,可以被修改。Windows NT 32位平臺(tái)下,指針的長(zhǎng)度(占用內(nèi)存的大?。?字節(jié),故sizeof(str)、sizeof(p)都為4。
第四篇:黑馬程序員:IOS面試寶典之UITableView與UICollectionView
黑馬程序員:IOS面試寶典之UITableView與UICollectionView 1.UITableView的重用機(jī)制?(或者如何在一個(gè)view上顯示多個(gè)tableView,tableView要求不同的數(shù)據(jù)源以及不同的樣式(要求自定義cell), 如何組織各個(gè)tableView的delegate和dataSource?請(qǐng)說(shuō)說(shuō)實(shí)現(xiàn)思路?)查看UITableView頭文件,會(huì)找到NSMutableArray*visiableCells,和NSMutableArray*reusableTableCells兩 個(gè)結(jié)構(gòu)。visiableCells內(nèi)保存當(dāng)前顯示的cells,reusableTableCells保存可重用的cells。TableView顯示之初,reusableTableCells為空,那么tableView dequeueReusableCellWithIdentifier:CellIdentifier返回nil。開(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。程序最開(kāi)始顯示TableView的情況是: 1.用[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] 創(chuàng)建10次cell,并給cell指定同樣的重用標(biāo)識(shí)(當(dāng)然,可以為不同顯示類(lèi)型的cell指定不同的標(biāo)識(shí))。并且10個(gè)cell全部都加 入到 visiableCells數(shù)組,reusableTableCells為空。
2.向下拖動(dòng)tableView,當(dāng)cell1完全移出屏幕,并且 cell11(它也是alloc出來(lái)的,原因同上)完全顯示出來(lái)的時(shí)候。cell11加入到visiableCells,cell1移出 visiableCells,cell1加入到reusableTableCells。
3.接著向下拖動(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就可 以正常重用了
2.在一個(gè)tableView 中需要自定義多種樣式的cell(兩種或三種),通常你如何實(shí)現(xiàn),說(shuō)說(shuō)思路即可? 比如:有100條數(shù)據(jù),iPhone一屏最多顯示10個(gè)cell。程序最開(kāi)始顯示TableView的情況是: 1.用[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] 創(chuàng)建10次cell,并給cell指定同樣的重用標(biāo)識(shí)(當(dāng)然,可以為不同顯示類(lèi)型的cell指定不同的標(biāo)識(shí))。并且10個(gè)cell全部都加 入到 visiableCells數(shù)組,reusableTableCells為空。
2.向下拖動(dòng)tableView,當(dāng)cell1完全移出屏幕,并且 cell11(它也是alloc出來(lái)的,原因同上)完全顯示出來(lái)的時(shí)候。cell11加入到visiableCells,cell1移出 visiableCells,cell1加入到reusableTableCells。
3.接著向下拖動(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就可 以正常重用了
3.UITableView的性能優(yōu)化? 滑動(dòng)的時(shí)候有種卡的感覺(jué)是為什么?怎么解決?
然而在使用第三方應(yīng)用時(shí),卻經(jīng)常遇到性能上的問(wèn)題,普遍表現(xiàn)在滾動(dòng)時(shí)比較卡,特別是table cell中包含圖片的情況時(shí)。實(shí)際上針對(duì)性地優(yōu)化一下就可以解決tableView滑動(dòng)的時(shí)候卡頓的問(wèn)題, 在iOS應(yīng)用中,UITableView應(yīng)該是使用率最高的視圖之一了。iPod、時(shí)鐘、日歷、備忘錄、Mail、天氣、照片、電話、短信、Safari、App Store、iTunes、Game Center?幾乎所有自帶的應(yīng)用中都能看到它的身影,可見(jiàn)它的重要性。然而在使用第三方應(yīng)用時(shí),卻經(jīng)常遇到性能上的問(wèn)題,普遍表現(xiàn)在滾動(dòng)時(shí)比較卡,特別是table cell中包含圖片的情況時(shí)。
實(shí)際上只要針對(duì)性地優(yōu)化一下: 1>同一時(shí)間其實(shí)只需要存在一屏幕的cell對(duì)象即可,不需要為每一行創(chuàng)建一個(gè)cell。
UITableView是UIScrollView的子類(lèi),因此它可以自動(dòng)響應(yīng)滾動(dòng)事件(一般為上下滾動(dòng))。它內(nèi)部包含0到多個(gè)UITableViewCell對(duì)象,每個(gè)table cell展示各自的內(nèi)容。當(dāng)新cell需要被顯示時(shí),就會(huì)調(diào)用tableView:cellForRowAtIndexPath:方法來(lái)獲取或創(chuàng)建一個(gè) cell;而不可視時(shí),它又會(huì)被釋放。由此可見(jiàn),同一時(shí)間其實(shí)只需要存在一屏幕的cell對(duì)象即可,不需要為每一行創(chuàng)建一個(gè)cell。此 外,UITableView還可以分為多個(gè)sections,每個(gè)區(qū)段都可以有自己的head、foot和cells。而在定位一個(gè)cell時(shí),就需要2 個(gè)字段了:在哪個(gè)section,以及在這個(gè)section的第幾行。這在iOS SDK中是用NSIndexPath來(lái)表述的,UIKit為其添加了indexPathForRow:inSection:這個(gè)創(chuàng)建方法。其他諸如編輯之類(lèi)的就不提了,因?yàn)楹捅疚臒o(wú)關(guān)。
介紹完原理,接下來(lái)就開(kāi)始優(yōu)化吧。
使用不透明視圖。
不透明的視圖可以極大地提高渲染的速度。因此如非必要,可以將table cell及其子視圖的opaque屬性設(shè)為YES(默認(rèn)值)。其中的特例包括背景色,它的alpha值應(yīng)該為1(例如不要使用clearColor);圖像的alpha值也應(yīng)該為1,或者在畫(huà)圖時(shí)設(shè)為不透明。
不要重復(fù)創(chuàng)建不必要的table cell。
前面說(shuō)了,UITableView只需要一屏幕的UITableViewCell對(duì)象即可。因此在cell不可見(jiàn)時(shí),可以將其緩存起來(lái),而在需要時(shí)繼續(xù)使用它即可。而UITableView也提供了這種機(jī)制,只需要簡(jiǎn)單地設(shè)置一個(gè)identifier即可:
static NSString *CellIdentifier = @“xxx”;UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];if(cell == nil){ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];} 值得一提的是,cell被重用時(shí),它內(nèi)部繪制的內(nèi)容并不會(huì)被自動(dòng)清除,因此你可能需要調(diào)用setNeedsDisplayInRect:或setNeedsDisplay方法。此 外,在添加table cell的時(shí)候,如果不需要?jiǎng)赢?huà)效果,最好不要使用insertRowsAtIndexPaths:withRowAnimation:方法,而是直接調(diào) 用reloadData方法。因?yàn)榍罢邥?huì)對(duì)所有indexPaths調(diào)用tableView:cellForRowAtIndexPath:方法,即便該 cell并不需要顯示(不知道是不是bug),這就可能創(chuàng)建大量多余的cell??闭`:只是在模擬器上測(cè)試如此,真機(jī)調(diào)試時(shí)沒(méi)有這種bug。
減少視圖的數(shù)目。
UITableViewCell包含了textLabel、detailTextLabel和imageView等view,而
你還可以自定義一些視圖放在它的contentView里。然而view是很大的對(duì)象,創(chuàng)建它會(huì)消耗較多資源,并且也影響渲染的性能。如果你的table cell包含圖片,且數(shù)目較多,使用默認(rèn)的UITableViewCell會(huì)非常影響性能。奇怪的是,使用自定義的view,而非預(yù)定義的view,明顯會(huì)快些。當(dāng)然,最佳的解決辦法還是繼承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ì)被高亮了。此外還可以創(chuàng)建CALayer,將內(nèi)容繪制到layer上,然后對(duì)cell的contentView.layer調(diào)用addSublayer:方法。這個(gè)例 子中,layer并不會(huì)顯著影響性能,但如果layer透明,或者有圓角、變形等效果,就會(huì)影響到繪制速度了。解決辦法可參見(jiàn)后面的預(yù)渲染圖像。
不要做多余的繪制工作。
在實(shí)現(xiàn)drawRect:的時(shí)候,它的rect參數(shù)就是需要繪制的區(qū)域,這個(gè)區(qū)域之外的不需要進(jìn)行繪制。例如上例中,就可以用CGRectIntersectsRect、CGRectIntersection或CGRectContainsRect判斷是否需要繪制image和text,然后再調(diào)用繪制方法。
預(yù)渲染圖像。
你會(huì)發(fā)現(xiàn)即使做到了上述幾點(diǎn),當(dāng)新的圖像出現(xiàn)時(shí),仍然會(huì)有短暫的停頓現(xiàn)象。解決的辦法就是在bitmap context里先將其畫(huà)一遍,導(dǎo)出成UIImage對(duì)象,然后再繪制到
屏幕,詳細(xì)做法可見(jiàn)《利用預(yù)渲染加速iOS設(shè)備的圖像顯示》。
不要阻塞主線程。
做到前幾點(diǎn)后,你的table view滾動(dòng)時(shí)應(yīng)該足夠流暢了,不過(guò)你仍可能讓用戶(hù)感到不爽。常見(jiàn)的現(xiàn)象就是在更新數(shù)據(jù)時(shí),整個(gè)界面卡住不動(dòng),完全不響應(yīng)用戶(hù)請(qǐng)求。出現(xiàn)這種現(xiàn)象的原因就是主線程執(zhí)行了耗時(shí)很長(zhǎng)的函數(shù)或方法,在其執(zhí)行完畢前,無(wú)法繪制屏幕和響應(yīng)用戶(hù)請(qǐng)求。其中最常見(jiàn)的就是網(wǎng)絡(luò)請(qǐng)求了,它通常都需要花費(fèi)數(shù)秒的時(shí)間,而你不應(yīng)該讓用戶(hù)等待那么久。解決辦法就是使用多線程,讓子線程去執(zhí)行這些函數(shù)或方法。這里面還有一個(gè)學(xué)問(wèn),當(dāng)下載線程數(shù)超過(guò)2時(shí),會(huì)顯著影響主線程的性能。因此在使用 ASIHTTPRequest時(shí),可以用一個(gè)NSOperationQueue
來(lái)維護(hù)下載請(qǐng)求,并將其
maxConcurrentOperationCount設(shè)為2。而NSURLRequest則可以配合GCD來(lái)實(shí)現(xiàn),或者使用NSURLConnection的setDelegateQueue:方法。當(dāng)然,在不需要響應(yīng)用戶(hù)請(qǐng)求時(shí),也可以增加下載線程數(shù),以加快下載速度:
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { if(!decelerate){ queue.maxConcurrentOperationCount = 5;} }(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { queue.maxConcurrentOperationCount = 2;} 此外,自動(dòng)載入更新數(shù)據(jù)對(duì)用戶(hù)來(lái)說(shuō)也很友好,這減少了用戶(hù)等待下載的時(shí)間。例如每次載入50條信息,那就可以在滾動(dòng)到倒數(shù)第10條以?xún)?nèi)時(shí),加載更多信息:
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { if(count-indexPath.row < 10 &&!updating){ updating = YES;[self update];} }// update方法獲取到結(jié)果后,設(shè)置updating為NO 還有一點(diǎn)要注意的就是當(dāng)圖片下載完
成后,如果cell是可見(jiàn)的,還需要更新圖像:
NSArray *indexPaths = [self.tableView indexPathsForVisibleRows];for(NSIndexPath *visibleIndexPath in indexPaths){ if(indexPath == visibleIndexPath){ MyTableViewCell *cell =(MyTableViewCell *)[self.tableView cellForRowAtIndexPath:indexPath];cell.image = image;[cell setNeedsDisplayInRect:imageRect];break;} }// 也可不遍歷,直接與頭尾相比較,看是否在中間即可。最后還是前面所說(shuō)過(guò)的insertRowsAtIndexPaths:withRowAnimation:方法,插入新行需要在主線程執(zhí)行,而一次插入很多行的話(例如50行),會(huì)長(zhǎng)時(shí)間阻塞主線程。而換成reloadData方法的話,瞬間就處理完了。l 4 tableview的cell里如何嵌套collection view?
思路同網(wǎng)易新聞?lì)愃? 用自定義的繼承自UITableViewCell的類(lèi), 在initWithFrame的構(gòu)造方法中, 初始化自定義的繼承自UICollectionView的類(lèi) 下拉和上拉的原理? 上拉和下拉的原理可以參照新浪微博的上拉和下拉刷新, 以tableView的上拉刷新為例:
1> 為了進(jìn)行無(wú)縫閱讀, 通過(guò)tableView的代理方法, willDisplayCell判斷是否是最后一行,2> 如果是最后一行, 在顯示最后一行的同時(shí), 判斷當(dāng)前是否存在上拉刷新 3> 如果當(dāng)前沒(méi)有上拉刷新, 就進(jìn)行加載數(shù)據(jù), 啟動(dòng)”橘花”
以tableView的下拉刷新為例: 1> 判斷當(dāng)前的上拉刷新視圖是否動(dòng)畫(huà)
2> 如果沒(méi)有動(dòng)畫(huà), 就不是上拉刷新 3> 然后下拉刷新加載數(shù)據(jù) 4> 加載完畢數(shù)據(jù)關(guān)閉刷新
第五篇:黑馬程序員:IOS面試寶典數(shù)據(jù)存儲(chǔ)
數(shù)據(jù)存儲(chǔ)(★★)
1、IOS中常用的數(shù)據(jù)存儲(chǔ)方式有哪些?
答:1.數(shù)據(jù)存儲(chǔ)有四種方案,NSUserDefault,KeyChain,File,DB.2.其中File有三種方式:plist,Archiver,Stream 3.DB包括core Data和FMDB
2、說(shuō)一說(shuō)你對(duì)sqlite的認(rèn)識(shí)
SQLite是目前主流的嵌入式關(guān)系型數(shù)據(jù)庫(kù),其最主要的特點(diǎn)就是輕量級(jí)、跨平臺(tái),當(dāng)前很多嵌入式操作系統(tǒng)都將其作為數(shù)據(jù)庫(kù)首選。雖然SQLite是一款輕型數(shù)據(jù)庫(kù),但是其功能也絕不亞于很多大型關(guān)系數(shù)據(jù)庫(kù)。學(xué)習(xí)數(shù)據(jù)庫(kù)就要學(xué)習(xí)其相關(guān)的定義、操作、查詢(xún)語(yǔ)言,也就是大家日常說(shuō)得SQL語(yǔ)句。和其他數(shù)據(jù)庫(kù)相比,SQLite中的SQL語(yǔ)法并沒(méi)有太大的差別,因此這里對(duì)于SQL語(yǔ)句的內(nèi)容不會(huì)過(guò)多贅述,大家可以參考SQLite中其他SQL相關(guān)的內(nèi)容,這里還是重點(diǎn)講解iOS中如何使用SQLite構(gòu)建應(yīng)用程序。先看一下SQLite數(shù)據(jù)庫(kù)的幾個(gè)特點(diǎn):
1.基于C語(yǔ)言開(kāi)發(fā)的輕型數(shù)據(jù)庫(kù)
2.在iOS中需要使用C語(yǔ)言語(yǔ)法進(jìn)行數(shù)據(jù)庫(kù)操作、訪問(wèn)(無(wú)法使用ObjC直接訪問(wèn),因?yàn)閘ibqlite3框架基于C語(yǔ)言編寫(xiě))
3.SQLite中采用的是動(dòng)態(tài)數(shù)據(jù)類(lèi)型,即使創(chuàng)建時(shí)定義了一種類(lèi)型,在實(shí)際操作時(shí)也可以存儲(chǔ)其他類(lèi)型,但是推薦建庫(kù)時(shí)使用合適的類(lèi)型(特別是應(yīng)用需要考慮跨平臺(tái)的情況時(shí))
4.建立連接后通常不需要關(guān)閉連接(盡管可以手動(dòng)關(guān)閉)
在iOS中操作SQLite數(shù)據(jù)庫(kù)可以分為以下幾步(注意先在項(xiàng)目中導(dǎo)入libsqlite3框架):
1.打開(kāi)數(shù)據(jù)庫(kù),利用sqlite3_open()打開(kāi)數(shù)據(jù)庫(kù)會(huì)指定一個(gè)數(shù)據(jù)庫(kù)文件保存路徑,如果文件存在則直接打開(kāi),否則創(chuàng)建并打開(kāi)。打開(kāi)數(shù)據(jù)庫(kù)會(huì)得到一個(gè)sqlite3類(lèi)型的對(duì)象,后面需要借助這個(gè)對(duì)象進(jìn)行其他操作。
2.執(zhí)行SQL語(yǔ)句,執(zhí)行SQL語(yǔ)句又包括有返回值的語(yǔ)句和無(wú)返回值語(yǔ)句。3.對(duì)于無(wú)返回值的語(yǔ)句(如增加、刪除、修改等)直接通過(guò)sqlite3_exec()函數(shù)執(zhí)行;
4.對(duì)于有返回值的語(yǔ)句則首先通過(guò)sqlite3_prepare_v2()進(jìn)行sql語(yǔ)句評(píng)估(語(yǔ)法檢測(cè)),然后通過(guò)sqlite3_step()依次取出查詢(xún)結(jié)果的每一行數(shù)據(jù),對(duì)于每行數(shù)據(jù)都可以通過(guò)對(duì)應(yīng)的sqlite3_column_類(lèi)型()方法獲得對(duì)應(yīng)列的數(shù)據(jù),如此反復(fù)循環(huán)直到遍歷完成。當(dāng)然,最后需要釋放句柄。
3、說(shuō)一說(shuō)你對(duì)FMDB的認(rèn)識(shí)
FMDB是一個(gè)處理數(shù)據(jù)存儲(chǔ)的第三方框架,框架是對(duì)sqlite的封裝,整個(gè)框架非常輕量級(jí)但又不失靈活性,而且更加面向?qū)ο?。FMDB有如下幾個(gè)特性:
1.FMDB既然是對(duì)于libsqlite3框架的封裝,自然使用起來(lái)也是類(lèi)似的,使用前也要打開(kāi)一個(gè)數(shù)據(jù)庫(kù),這個(gè)數(shù)據(jù)庫(kù)文件存在則直接打開(kāi)否則會(huì)創(chuàng)建并打開(kāi)。這里FMDB引入了一個(gè)MFDatabase對(duì)象來(lái)表示數(shù)據(jù)庫(kù),打開(kāi)數(shù)據(jù)庫(kù)和后面的數(shù)據(jù)庫(kù)操作全部依
賴(lài)此對(duì)象。
2.對(duì)于數(shù)據(jù)庫(kù)的操作跟前面KCDbManager的封裝是類(lèi)似的,在FMDB中FMDatabase類(lèi)提供了兩個(gè)方法executeUpdate:和executeQuery:分別用于執(zhí)行無(wú)返回結(jié)果的查詢(xún)和有返回結(jié)果的查詢(xún)。當(dāng)然這兩個(gè)方法有很多的重載這里就不詳細(xì)解釋了。唯一需要指出的是,如果調(diào)用有格式化參數(shù)的sql語(yǔ)句時(shí),格式化符號(hào)使用“?”而不是“%@”、等。
3.我們知道直接使用libsqlite3進(jìn)行數(shù)據(jù)庫(kù)操作其實(shí)是線程不安全的,如果遇到多個(gè)線程同時(shí)操作一個(gè)表的時(shí)候可能會(huì)發(fā)生意想不到的結(jié)果。為了解決這個(gè)問(wèn)題建議在多線程中使用FMDatabaseQueue對(duì)象,相比FMDatabase而言,它是線程安全的。
4.將事務(wù)放到FMDB中去說(shuō)并不是因?yàn)橹挥蠪MDB才支持事務(wù),而是因?yàn)镕MDB將其封裝成了幾個(gè)方法來(lái)調(diào)用,不用自己寫(xiě)對(duì)應(yīng)的sql而已。其實(shí)在在使用libsqlite3操作數(shù)據(jù)庫(kù)時(shí)也是原生支持事務(wù)的(因?yàn)檫@里的事務(wù)是基于數(shù)據(jù)庫(kù)的,F(xiàn)MDB還是使用的SQLite數(shù)據(jù)庫(kù)),只要在執(zhí)行sql語(yǔ)句前加上“begin transaction;”執(zhí)行完之后執(zhí)行“commit transaction;”或者“rollback transaction;”進(jìn)行提交或回滾即可。另外在Core Data中大家也可以發(fā)現(xiàn),所有的增、刪、改操作之后必須調(diào)用上下文的保存方法,其實(shí)本身就提供了事務(wù)的支持,只要不調(diào)用保存方法,之前所有的操作是不會(huì)提交的。在FMDB中FMDatabase有beginTransaction、commit、rollback三個(gè)方法進(jìn)行開(kāi)啟事務(wù)、提交事務(wù)和回滾事務(wù)。
4、說(shuō)一說(shuō)你對(duì)Core Data的認(rèn)識(shí)
Core Data使用起來(lái)相對(duì)直接使用SQLite3的API而言更加的面向?qū)ο?,操作過(guò)
程通常分為以下幾個(gè)步驟:
1.創(chuàng)建管理上下文
創(chuàng)建管理上下可以細(xì)分為:加載模型文件->指定數(shù)據(jù)存儲(chǔ)路徑->創(chuàng)建對(duì)應(yīng)數(shù)據(jù)類(lèi)型的存儲(chǔ)->創(chuàng)建管理對(duì)象上下方并指定存儲(chǔ)。
經(jīng)過(guò)這幾個(gè)步驟之后可以得到管理對(duì)象上下文NSManagedObjectContext,以后所有的數(shù)據(jù)操作都由此對(duì)象負(fù)責(zé)。同時(shí)如果是第一次創(chuàng)建上下文,Core Data會(huì)自動(dòng)創(chuàng)建存儲(chǔ)文件(例如這里使用SQLite3存儲(chǔ)),并且根據(jù)模型對(duì)象創(chuàng)建對(duì)應(yīng)的表結(jié)構(gòu)。
2.查詢(xún)數(shù)據(jù)
對(duì)于有條件的查詢(xún),在Core Data中是通過(guò)謂詞來(lái)實(shí)現(xiàn)的。首先創(chuàng)建一個(gè)請(qǐng)求,然后設(shè)置請(qǐng)求條件,最后調(diào)用上下文執(zhí)行請(qǐng)求的方法。
3.插入數(shù)據(jù)
插入數(shù)據(jù)需要調(diào)用實(shí)體描述對(duì)象NSEntityDescription返回一個(gè)實(shí)體對(duì)象,然后設(shè)置對(duì)象屬性,最后保存當(dāng)前上下文即可。這里需要注意,增、刪、改操作完最后必須調(diào)用管理對(duì)象上下文的保存方法,否則操作不會(huì)執(zhí)行。
4.刪除數(shù)據(jù)
刪除數(shù)據(jù)可以直接調(diào)用管理對(duì)象上下文的deleteObject方法,刪除完保存上下文即可。注意,刪除數(shù)據(jù)前必須先查詢(xún)到對(duì)應(yīng)對(duì)象。
5.修改數(shù)據(jù)
修改數(shù)據(jù)首先也是取出對(duì)應(yīng)的實(shí)體對(duì)象,然后通過(guò)修改對(duì)象的屬性,最后保存上下文。
5、OC中有哪些數(shù)據(jù)存儲(chǔ)方式,各有什么區(qū)別? OC中有四種數(shù)據(jù)存儲(chǔ)方式: 1).NSUserDefaults,用于存儲(chǔ)配置信息 2).SQLite,用于存儲(chǔ)查詢(xún)需求較多的數(shù)據(jù) 3).CoreData,用于規(guī)劃應(yīng)用中的對(duì)象
4).使用基本對(duì)象類(lèi)型定制的個(gè)性化緩存方案.NSUserDefaults:對(duì)象中儲(chǔ)存了系統(tǒng)中用戶(hù)的配置信息,開(kāi)發(fā)者可以通過(guò)這個(gè)實(shí)例對(duì)象對(duì)這些已有的信息進(jìn)行修改,也可以按照自己的需求創(chuàng)建新的配置項(xiàng)。SQLite擅長(zhǎng)處理的數(shù)據(jù)類(lèi)型其實(shí)與NSUserDefaults差不多,也是基礎(chǔ)類(lèi)型的小數(shù)據(jù),只是從組織形式上不同。開(kāi)發(fā)者可以以關(guān)系型數(shù)據(jù)庫(kù)的方式組織數(shù)據(jù),使用SQL DML來(lái)管理數(shù)據(jù)。一般來(lái)說(shuō)應(yīng)用中的格式化的文本類(lèi)數(shù)據(jù)可以存放在數(shù)據(jù)庫(kù)中,尤其是類(lèi)似聊天記錄、Timeline等這些具有條件查詢(xún)和排序需求的數(shù)據(jù)。CoreData是一個(gè)管理方案,它的持久化可以通過(guò)SQLite、XML或二進(jìn)制文件儲(chǔ)存。它可以把整個(gè)應(yīng)用中的對(duì)象建模并進(jìn)行自動(dòng)化的管理。從歸檔文件還原模型時(shí)CoreData并不是一次性把整個(gè)模型中的所有數(shù)據(jù)都載入內(nèi)存,而是根據(jù)運(yùn)行時(shí)狀態(tài),把被調(diào)用到的對(duì)象實(shí)例載入內(nèi)存??蚣軙?huì)自動(dòng)控制這個(gè)過(guò)程,從而達(dá)到控制內(nèi)存消耗,避免浪費(fèi)。無(wú)論從設(shè)計(jì)原理還是使用方法上看,CoreData都比較復(fù)雜。因此,如果僅僅是考慮緩存數(shù)據(jù)這個(gè)需求,CoreData絕對(duì)不是一個(gè)優(yōu)選方案。CoreData的使用場(chǎng)景在于:整個(gè)應(yīng)用使用CoreData規(guī)劃,把應(yīng)用內(nèi)的數(shù)據(jù)通過(guò)CoreData建模,完全基于CoreData架構(gòu)應(yīng)用。使用基本對(duì)象類(lèi)型定制的個(gè)性化緩存方案:從需求出發(fā)分析緩存數(shù)據(jù)有哪些要求:按Key查找,快速讀取,寫(xiě)入不影響正常操作,不浪費(fèi)內(nèi)存,支持歸檔。這些都是基本需求,那么再進(jìn)一步或許還需要固定緩存項(xiàng)數(shù)量,支持隊(duì)列緩存,緩存過(guò)期等。
數(shù)據(jù)存儲(chǔ)這一塊,面試常問(wèn), 你常用哪一種數(shù)據(jù)存儲(chǔ)?什么是序列化?sqlite是直接用它還是用封裝了它的第三方庫(kù)?尤其是會(huì)問(wèn)sqlite和core data的區(qū)別?
5、IOS平臺(tái)怎么做數(shù)據(jù)的持久化?coredata和sqlite有無(wú)必然聯(lián)系?coredata是一個(gè)關(guān)系型數(shù)據(jù)庫(kù)嗎?
iOS中可以有四種持久化數(shù)據(jù)的方式: 屬性列表、對(duì)象歸檔、SQLite3和Core Data coredata可以使你以圖形界面的方式快速的定義app的數(shù)據(jù)模型,同時(shí)在你的代碼中容易獲取到它。coredata提供了基礎(chǔ)結(jié)構(gòu)去處理常用的功能,例如保存,恢復(fù),撤銷(xiāo)和重做,允許你在app中繼續(xù)創(chuàng)建新的任務(wù)。在使用coredata的時(shí)候,你不用安裝額外的數(shù)據(jù)庫(kù)系統(tǒng),因?yàn)閏oredata使用內(nèi)置的sqlite數(shù)據(jù)庫(kù)。coredata將你app的模型層放入到一組定義在內(nèi)存中的數(shù)據(jù)對(duì)象。coredata會(huì)追蹤這些對(duì)象的改變,同時(shí)可以根據(jù)需要做相應(yīng)的改變,例如用戶(hù)執(zhí)行撤銷(xiāo)命令。當(dāng)coredata在對(duì)你app數(shù)據(jù)的改變進(jìn)行保存的時(shí)候,core data會(huì)把這些數(shù)據(jù)歸檔,并永久性保存。mac os x中sqlite庫(kù),它是一個(gè)輕量級(jí)功能強(qiáng)大的關(guān)系數(shù)據(jù)引擎,也很容易嵌入到應(yīng)用程序。可以在多個(gè)平臺(tái)使用,sqlite是一個(gè)輕量級(jí)的嵌入式sql數(shù)據(jù)庫(kù)編程。與coredata框架不同的是,sqlite是使用程序式的,sql的主要的API來(lái)直接操作數(shù)據(jù)表。Core Data不是一個(gè)關(guān)系型數(shù)據(jù)庫(kù),也不是關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng)(RDBMS)。雖然Core Dta支持SQLite作為一種存儲(chǔ)類(lèi)型, 但它不能使用任意的SQLite數(shù)據(jù)庫(kù)。Core Data在使用的過(guò)程種自己創(chuàng)建這個(gè)數(shù)據(jù)庫(kù)。Core Data支持對(duì)
一、對(duì)多的關(guān)系。
6、如果后期需要增加數(shù)據(jù)庫(kù)中的字段怎么實(shí)現(xiàn),如果不使用CoreData呢?
編寫(xiě)SQL語(yǔ)句來(lái)操作原來(lái)表中的字段 增加表字段
ALTER TABLE 表名 ADD COLUMN 字段名字段類(lèi)型;? 刪除表字段
ALTER TABLE 表名 DROP COLUMN 字段名;
.修改表字段
ALTER TABLE 表名 RENAME COLUMN 舊字段名 TO 新字段名;
7、SQLite數(shù)據(jù)存儲(chǔ)是怎么用?
添加SQLite動(dòng)態(tài)庫(kù):
導(dǎo)入主頭文件:#import
8、簡(jiǎn)單描述下客戶(hù)端的緩存機(jī)制?
1>緩存可以分為:內(nèi)存數(shù)據(jù)緩存、數(shù)據(jù)庫(kù)緩存、文件緩存 2>每次想獲取數(shù)據(jù)的時(shí)候 3>先檢測(cè)內(nèi)存中有無(wú)緩存
4>再檢測(cè)本地有無(wú)緩存(數(shù)據(jù)庫(kù)文件)5>最終發(fā)送網(wǎng)絡(luò)請(qǐng)求
6>將服務(wù)器返回的網(wǎng)絡(luò)數(shù)據(jù)進(jìn)行緩存(內(nèi)存、數(shù)據(jù)庫(kù)、文件),以便下次讀取
9、你實(shí)現(xiàn)過(guò)多線程的Core Data么?NSPersistentStoreCoordinator,NSManagedObjectContext和NSManagedObject中的哪些需要在線程中創(chuàng)建或者傳遞?你是用什么樣的策略來(lái)實(shí)現(xiàn)的?
1>CoreData是對(duì)SQLite數(shù)據(jù)庫(kù)的封裝
2>CoreData中的NSManagedObjectContext在多線程中不安全
3>如果想要多線程訪問(wèn)CoreData的話,最好的方法是一個(gè)線程一個(gè)NSManagedObjectContext 4>每個(gè)NSManagedObjectContext對(duì)象實(shí)例都可以使用同一個(gè)NSPersistentStoreCoordinator實(shí)例,這是因?yàn)镹SManagedObjectContext會(huì)在便用NSPersistentStoreCoordinator前上鎖
10、core data數(shù)據(jù)遷移
博客地址: http://blog.csdn.net/jasonblog/article/details/17842535
11、FMDB的使用和對(duì)多張表的處理
博客地址: http://blog.csdn.net/wscqqlucy/article/details/8464398
12、說(shuō)說(shuō)數(shù)據(jù)庫(kù)的左連接和右連接的區(qū)別
數(shù)據(jù)庫(kù)左連接和右連接的區(qū)別:主表不一樣通過(guò)左連接和右連接,最小條數(shù)為3(記錄條數(shù)較小的記錄數(shù)),最大條數(shù)為12(3×4)技術(shù)博客的地址 : http://