iOS程序員面試分類模擬18_第1頁
iOS程序員面試分類模擬18_第2頁
iOS程序員面試分類模擬18_第3頁
iOS程序員面試分類模擬18_第4頁
iOS程序員面試分類模擬18_第5頁
已閱讀5頁,還剩17頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

iOS程序員面試分類模擬18簡答題1.

Objective-C中的id類型指的是什么?id、nil代表什么?正確答案:id表示Objective-C對象的類型在編寫代碼時(shí)(編譯期)不確定,視為任意(江南博哥)Object類型(即指向任意繼承了NSObject的類的對象或者NSObject對象的指針),直到程序運(yùn)行起來時(shí)才最終確定其類型。

id類似于C/C++中的void*,但id和void*并非完全一樣。id是一個指向繼承了NSObject的Objective-C對象的指針,注意id是一個指針,雖然省略了*號。id和C語言的void*之間需要通過bridge關(guān)鍵字來顯式的橋接轉(zhuǎn)換。具體轉(zhuǎn)換方式示例代碼如下:

idnsobj=[[NSObjectalloc]init];

void*p=(__bridgevoid*)nsobj;

idnsobj=(__bridgeid)p;

Objective-C中的nil定義在objc/objc.h中,表示一個指向空的Objctive-C對象的指針。例如weak修飾的弱引用對象在指向的對象釋放時(shí)會自動將指針置為nil,即空對象指針,來防止指針懸掛。

2.

如何自定義UIViewController之間的轉(zhuǎn)場動畫?正確答案:在實(shí)際開發(fā)中,程序界面常常需要在不同的控制器視圖之間切換,常用的跳轉(zhuǎn)方式有push、pop、present和dismiss等。如果使用這些方式,那么系統(tǒng)會提供默認(rèn)的動畫效果,例如當(dāng)使用-pushViewController:animation:的時(shí)候會產(chǎn)生一個新視圖從右往左推開舊視圖的動畫效果。但是有時(shí)候希望跳轉(zhuǎn)方式能以其他的動畫效果展示,這時(shí)就需要自定義轉(zhuǎn)場動畫。

在開始自定義轉(zhuǎn)場動畫之前,有必要先了解幾個簡單的概念。

1)fromView和toView,在很多API中常常會有fromView和toView,ffomView表示當(dāng)前視圖,即跳轉(zhuǎn)前的視圖,而toView代表跳轉(zhuǎn)后的視圖(或稱為跳轉(zhuǎn)的目標(biāo)視圖)。

2)presentedViewController和presentingViewController,這也是一組相對的概念,presentedViewController表示被modal出的視圖控制器(或稱為跳轉(zhuǎn)的目標(biāo)視圖控制器),而presentingViewController代表源視圖控制器。

3)UIViewControllerTransitioningDelegate協(xié)議用于為跳轉(zhuǎn)動畫提供實(shí)現(xiàn)了UIViewControllerAnimatedTransitioning協(xié)議的對象。

4)UIViewControllerAnimatedTransitioning協(xié)議主要用于控制動畫的展示時(shí)間和動畫展示邏輯。

5)UIViewControllerInteractiveTransitioning協(xié)議即交互式轉(zhuǎn)場動畫代理,這個協(xié)議主要用于交互式動畫。

6)UIViewControllerContextTransitioning協(xié)議即轉(zhuǎn)場動畫上下文協(xié)議,它的作用在于為動畫提供必備的信息。開發(fā)者不應(yīng)該緩存任何關(guān)于動畫的信息,而是應(yīng)該從轉(zhuǎn)場動畫上下文中獲取,這樣可以保證總是獲取到最新的、正確的信息。

要實(shí)現(xiàn)整個轉(zhuǎn)場動畫邏輯需要兩組必需的元素,其一是代表頁面跳轉(zhuǎn)關(guān)系的兩個控制器對象,其二是動畫執(zhí)行邏輯。以下是實(shí)現(xiàn)動畫的步驟:

1)為源控制器和目標(biāo)控制器分別設(shè)置一個遵守UIViewControllerAnimatedTransitioning協(xié)議的代理對象。當(dāng)然也可以設(shè)置為同一個對象。

2)調(diào)用對應(yīng)的跳轉(zhuǎn)方法。此時(shí)系統(tǒng)會自動請求動畫代理提供動畫邏輯對象。

下面的例子展示了一個自定義的跳轉(zhuǎn)動畫效果。

/*設(shè)置transitioningDelegate為當(dāng)前控制器*/

-(void)startCustomControllerTransitionAniamtion1:(UITouch*)touch{

_touchPoint=[touchlocationInView:self.view];

TouchExampleController*VC=[TouchExampleControllernew];

vc.type=3;

vc.transitioningDelegate=self;

[selfpresentViewController:vcanimated:YEScompletion:nil];

}

/*當(dāng)modal時(shí),系統(tǒng)會自動調(diào)用此方法返回一個遵守UIViewControllerAnimatedTransitioning協(xié)議的對象*/

-(nullableid<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController*)presentedpresentingController:(UIViewController*)presentingsourceController:(UIViewController*)source{

TransitionAnimator*animator=[TransitionAnimatornew];

/*將單擊坐標(biāo)傳過去,以確定動畫開始的點(diǎn)*/

animator.touchPoint=_touchPoint;

returnanimator:

}

/*在TransitionAnimator類實(shí)現(xiàn)中,實(shí)現(xiàn)UIViewControllerAnimatedTransitioning協(xié)議*/

@implementationTransitionAnimator

/*設(shè)置動畫時(shí)長*/

-(NSTimeInterval)transitionDuration:(nullableid<UIViewControllerContextTransitioning>)transitionContext{

return1;

}

/*設(shè)置動畫*/

-(void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext{

/*從上下文中獲取必需信息*/

UIView*fromV=[transitionContextViewForKey:

UITransitionContextFromViewKey];

UIView*toV=[transitionContextviewForKey:UITransitionContextToViewKey];

UIView*containerView=[transitionContextcontainerView];

/*將視圖添加到containerView中*/

[containerViewaddSubview:fromV];

[containerViewaddSubview:toV];

CGFloatscreenWidth=[UIScreenmainScreen].bounds.size.width;

CGFloatscreenHeight=[UIScreenmainScreen].bounds.size.height;

CGPointtempPoint=[containerViewconvertPoint:self.touchPointfromView:[transitionContextviewForKey:UITransitionContextFromViewKey]];

CGRectrect=CGRectMake(tempPoint.x-1,tempPoint.y-1,2,2);

/*使用UIBerizerPath繪制動畫的開始路徑和結(jié)束路徑*/

UIBezierPath*startPath=[UIBezierPathbezierPathWithOvalInRect:reet];

UIBezierPath*endPath=[UIBezierPathbezierPathWithArcCenter:containerView.centerradius:sqrt(screenHeight*screenHeight+screenWidth*screenWidth)startAngle:0endAngle:M_PI*2clockwise:YES];

/*設(shè)置maskLayer*/

CAShapeLayer*maskLayer=[CAShapeLayerlayer];

maskLayer.path=endPath.CGPath;

toV.layer.mask=maskLayer;

/*設(shè)置動畫*/

CABasicAnimation*animation=[CABasicAnimationanimationWithKeyPath:@"path"];

animation.delegate=self;

animation.fromValue=(id)startPath.CGPath;

animation.toValue=(id)endPath.CGPath;

animation.duration=[selftransitionDuration:transitionContext];

[maskLayeraddAnimation:animationforKey:@"custom"];

callback=^{

toV.layer.mask=nil;

/*動畫結(jié)束后一定要調(diào)用此方法完成過渡動畫*/

[transitionContextcompleteTransition:![transitionContexttransitionWasCancelled]];

};

}

-(void)animationDidStop:(CAAnimation*)animfinished:(BOOL)flag{

callback();

}

動畫效果是從單擊坐標(biāo)點(diǎn)開始,以圓圈的形式逐漸展開,如圖所示。

轉(zhuǎn)場動畫

3.

什么是目標(biāo)-動作機(jī)制?正確答案:目標(biāo)-動作(target-action)機(jī)制是一種設(shè)計(jì)模式,用于一個對象在某個事件發(fā)生時(shí)向另一個對象發(fā)送消息。消息中要包含一個selector,用于確定要觸發(fā)的方法,該方法即該機(jī)制中的動作。還要包含一個target(目標(biāo)),表示消息的接收者,例如一個控件,或者更為常見的是它的單元,以插座變量的形式保有其動作消息的目標(biāo)。

目標(biāo)-動作機(jī)制符合軟件開發(fā)中“高內(nèi)聚,低耦合”的設(shè)計(jì)目標(biāo),降低模塊間的耦合度,同時(shí)增強(qiáng)了模塊內(nèi)部的聚合度。目標(biāo)一動作機(jī)制主要用于MVC設(shè)計(jì)模式中V到C的通信,通過該機(jī)制,充當(dāng)V的組件只要在UI事件發(fā)生時(shí)通知C即可,之后的邏輯處理全交由C去進(jìn)一步處理。

典型的例子是UIButton的單擊事件和方法的綁定,當(dāng)按鈕事件發(fā)生時(shí),會觸發(fā)接收者對于該事件所綁定的方法。這里的UIButton按鈕即MVC中的V組件,通過目標(biāo)一動作機(jī)制綁定的selector方法即屬于C中的后續(xù)邏輯處理部分。

[buttonaddTarget:selfaction:@selector(click:)forControlEvents:UIControlEventTouchUpInside];

4.

什么是鍵值編碼KVC?鍵路徑是什么?什么是鍵值觀察KVC?正確答案:1.鍵值編碼KVC

鍵值編碼(KVC)是一種在NSKeyValueCoding非正式協(xié)議下使用字符串標(biāo)志間接訪問對象屬性的一種機(jī)制,也就是訪問對象變量的一種特殊的捷徑。如果一個對象符合鍵值編碼的約定,那么它的屬性就可以通過一個準(zhǔn)確的、唯一的字符串(鍵路徑字符串)參數(shù)進(jìn)行訪問,類似于將所有對象看作Dictionary,鍵路徑為key(實(shí)際為keypath),屬性值即value,通過鍵路徑訪問屬性值。鍵值編碼的間接訪問方式其實(shí)是傳統(tǒng)實(shí)例變量的存取方法訪問的一種替代,也就是另外一種可以訪問對象變量的方法。其中,注意鍵值編碼可以暴力訪問對象的任何變量,無論是否是pirvate私有類型的變量。

開發(fā)者通常是通過存取方法來訪問對象的屬性的,getter方法返回屬性的值,setter方法設(shè)置屬性的值。對于實(shí)例對象,可以直接通過存取方法或者變量名來訪問對象的屬性,但是隨著屬性數(shù)量的增加和對象變量的嵌套深度增大,訪問代碼會隨之增多。相比之下,通過鍵值編碼就可以簡潔而穩(wěn)定地對所有屬性進(jìn)行訪問。

鍵值編碼是Cocoa框架中很基礎(chǔ)的一個概念,像KVO、Cocoa綁定、CoreData等都是基于KVC的。

2.鍵路徑

鍵路徑就是鍵值編碼中某個屬性的key,一個由連續(xù)鍵名組成的字符串,鍵名即屬性名,鍵名之間用點(diǎn)隔開,用于指定一個連接在一起的對象性質(zhì)序列。鍵路徑使開發(fā)者可以獨(dú)立于模型實(shí)現(xiàn)的方式指定相關(guān)對象的性質(zhì)。通過鍵路徑,可以指定對象圖中的一個任意深度的路徑,使其指向相關(guān)對象的某個特定的屬性。

3.鍵值觀察KVO

鍵值觀察(KVO),是基于鍵值編碼實(shí)現(xiàn)的一種觀察者機(jī)制,提供了觀察某一屬性變化的監(jiān)聽方法,用來簡化代碼,優(yōu)化邏輯和組織。

這里提供一個最基本的KVO和KVC的使用示例。假設(shè)有一個專業(yè)類Major,Major有一個專業(yè)名(majorName)私有屬性;一個學(xué)生類Student,Student有一個姓名(name)私有屬性,同時(shí)還有一個專業(yè)(Major)對象變量,這樣就出現(xiàn)了簡單的Major和Student的對象嵌套。Major和Student都繼承自NSObject,都符合鍵值編碼約定,可以定義一個Student變量對其進(jìn)行鍵值編碼和鍵值觀察。示例代碼如下:

/*1.專業(yè)類模型:Major.h*/

@interfaceMajor:NSObject{

@private

NSString*majorName;//私有實(shí)例變量專業(yè)名稱

}

@end

/*2.學(xué)生類模型:Student.h*/

@interfaceStudent:NSObject{

@private

NSString*name;//私有實(shí)例變量姓名

}

@property(nonatomic,strong)Major*major;//學(xué)生專業(yè)

/*3.kvc和kvo之間基本使用方法*/

#import"Student.h"

#import"Major.h"

@interfaceViewController()

@property(nonatomic,strong)Student*student;

@end

@implementationViewController

(void)viewDidLoad{

[superviewDidLoad];

/*初始化學(xué)生Student對象*/

_student=[[Studentalloc]init];

/*初始化學(xué)生的專業(yè)Major對象*/

_student.major=[[Majoralloc]init];

/*1.set:通過KVC設(shè)置Student對象的值(可以強(qiáng)行訪問private變量)*/

[_studentsetValue:@"Sam"forKey:@"name"];

[_studentsetValue:@"ComputerScience"forKeyPath:@"major.majorName"];

/*2.get:通過KVC讀取Student對象的值(可以強(qiáng)行訪問private變量)*/

NSLog(@"%@",[_studentvalueForKey:@"name"]);

NSLog(@"%@",[_studentvalueForKeyPath:@"major.majorName"]);

/*

**3.kvo:添加當(dāng)前控制器為鍵路徑major.majorName的一個觀察者,

**如果major.majorNalne的值改變,那么會通知當(dāng)前控制器從而

**自動調(diào)用下面的observeValueForKeyPath方法,這里傳遞舊值和新值

*/

[_studentaddObserver:selfforKeyPath:@"major.majorName"options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNewcontext:nil];

/*3s后改變major.majorName的值*/

dispatch_after(dispatch_time(DISPATCH_TIMENOW,(int64_t)(3*NSEC_PER_SEC)),dispatch_get_main_queue(),^{

[_studentsetValue:@"SoftwareEngineer"forKeyPath:@"major.majorName"];

});

}

/*監(jiān)聽keyPath值的變化*/

-(void)observeValueForKeyPath:(NSString*)keyPathofObject:(id)objectchange:(NSDictionary<NSKeyValueChangeKey,id>*)changecontext:(void*)context{

if([keyPathisEqual:@"major.majorName"]){

/*獲取變化前后的值并打印*/

NSString*oldValue=[changeobjectForKey:NSKeyVatueChangeOldKey];

NSString*newValue=[changeobjectForKey:NSKeyValueChangeNewKey];

NSLog(@"major.majorNamevaluechanged:oldValue:%@newValue:%@",oldValue,newValue);

}

else{

[superobserveValueForKeyPath:keyPathofObject:objectchange:changecontext:context];

}

}

/*移除觀察者釋放資源,防止資源泄漏*/

-(void)dealloc{

[_StudentremoveObserver:selfforKeyPath:@"major.majorName"];

}

@end

可以看到major.majorName就是一個由兩個鍵連接起來的基本鍵路徑,相當(dāng)于用它可以直接訪問屬性的屬性;使用addObserver方法將當(dāng)前控制器注冊為Student對象的觀察者,當(dāng)Student中鍵路徑major.majorName下的值發(fā)生改變時(shí)會通知當(dāng)前控制器,觸發(fā)observeValueForKeyPath監(jiān)聽方法。

5.

objective-C是如何實(shí)現(xiàn)內(nèi)存管理的?正確答案:Objective-C的內(nèi)存管理本質(zhì)上是通過引用計(jì)數(shù)實(shí)現(xiàn)的,每次RunLoop都會檢查對象的引用計(jì)數(shù),如果引用計(jì)數(shù)為0,那么說明該對象已經(jīng)沒有再被使用了,此時(shí)可以對其進(jìn)行釋放了。其中,引用計(jì)數(shù)可以大體分為3種:MRC、ARC和內(nèi)存池。

那么引用計(jì)數(shù)是如何操作的呢?其實(shí)不論哪種引用計(jì)數(shù)方式,它們本質(zhì)上都是在合適的時(shí)機(jī)將對象的引用計(jì)數(shù)加1或者減1。

所以對于引用計(jì)數(shù)可以總結(jié)如下:

1)使對象引用計(jì)數(shù)加1的常見操作有alloc、copy、retain。

2)使對象引用計(jì)數(shù)減1的常見操作有release、autorealease。

自動釋放池是一個統(tǒng)一來釋放一組對象的容器,在向?qū)ο蟀l(fā)送autorelease消息時(shí),對象并沒有立即釋放,而是將對象加入到最新的自動釋放池(即將該對象的引用交給自動釋放池,之后統(tǒng)一調(diào)用release),自動釋放池會在程序執(zhí)行到作用域結(jié)束的位置時(shí)進(jìn)行drain釋放操作,這個時(shí)候會對池中的每一個對象都發(fā)送release消息來釋放所有對象。這樣其實(shí)就實(shí)現(xiàn)了這些對象的延遲釋放。

自動釋放池釋放的時(shí)機(jī)指自動釋放池內(nèi)的所有對象是在什么時(shí)候釋放的,這里要提到程序的運(yùn)行周期RunLoop。對于每一個新的RunLoop,系統(tǒng)都會隱式地創(chuàng)建一個autoreleasepool,RunLoop結(jié)束時(shí)自動釋放池便會進(jìn)行對象釋放操作。autorelease和release的區(qū)別主要是引用計(jì)數(shù)減1的時(shí)機(jī)不同,autorelease是在對象的使用真正結(jié)束的時(shí)候才做引用計(jì)數(shù)減1,而不是收到消息立馬釋放。

retain、release和autorelease的內(nèi)部實(shí)現(xiàn)代碼如下:

-(id)retain{

/*對象引用計(jì)數(shù)加1*/

NSIncrementExtraRefCount(self);

returnself;

}

-(void)release{

/*對象引用計(jì)數(shù)減1,之后如果引用計(jì)數(shù)為0,那么釋放*/

if(NSDecrementExtraRefCountWasZero(self)){

NSDeallocateObject(self);

}

}

-(id)autorelease{

/*添加對象到自動釋放池*/

[NSAutoreteasePooladdObject:self];

returnself;

}

6.

執(zhí)行下面的代碼會發(fā)生什么后果?

Ball*ball=[[[[Ballalloc]init]autorelease]autorelease];正確答案:上面的代碼會導(dǎo)致程序崩潰,因?yàn)檫B續(xù)兩次調(diào)用autorelease方法后,對象被加入到自動釋放池兩次。當(dāng)對象被移除時(shí),自動釋放池將其釋放了不止一次,其中第二次釋放必定導(dǎo)致崩潰。

7.

什么是“應(yīng)用瘦身”?正確答案:“應(yīng)用瘦身”(Appthinning)是美國蘋果公司自iOS9發(fā)布的新特性,它能對AppleStore和操作系統(tǒng)進(jìn)行優(yōu)化,它根據(jù)用戶的具體設(shè)備型號,在保證應(yīng)用特性完整的前提下,盡可能地壓縮和減少應(yīng)用程序安裝包的體積,也就是盡可能減少應(yīng)用程序?qū)τ脩粼O(shè)備內(nèi)存的占用,從而減小用戶下載應(yīng)用程序的負(fù)擔(dān)。Appthinning的實(shí)現(xiàn)主要有以下3種方法:Slicing、Bitcode和On-DemandResources。以下將對這3種方法進(jìn)行介紹。

1.Slicing

在開發(fā)者將完整的應(yīng)用安裝包發(fā)布到AppleStore之后,AppleStore會根據(jù)下載用戶的目標(biāo)設(shè)備型號創(chuàng)建相應(yīng)的應(yīng)用變體(variantsoftheappbundle)。這些變體只包含可執(zhí)行的結(jié)構(gòu)和資源等必要部分,而不需要讓用戶下載開發(fā)者提供的完整安裝包。下圖展示了從開發(fā)者使用Xcode開發(fā)完整應(yīng)用并發(fā)布到AppleStore后被用戶下載到不同設(shè)備上的流程。

應(yīng)用發(fā)布下載流程圖

2.Bitcode

Bitcode是iOS中開發(fā)者的一個可選項(xiàng),如果工程中開啟了Bitcode,那么蘋果會對開發(fā)者編譯后的應(yīng)用二進(jìn)制文件進(jìn)行二次優(yōu)化,將其轉(zhuǎn)換成一種中間代碼(Bitcode),在AppleStore上進(jìn)行編譯和鏈接。Bitcode屬于官方的一種新的優(yōu)化技術(shù),由于很多第三方庫不支持Bitcode,所以很多時(shí)候不得不關(guān)閉Bitcode以保證程序的正常運(yùn)行。

3.On-DemandResources

它是一種“按需供給”的資源加載方式,用戶下載應(yīng)用程序時(shí)不需要下載應(yīng)用程序完整的資源,而是在用戶使用過程中到了某個階段需要用到某些資源(圖片資源和聲音資源等)時(shí),才從后臺的服務(wù)器下載同步,這種方式類似于資源的延遲加載,可以減輕本地內(nèi)存的負(fù)擔(dān)。這種方式在游戲等對資源使用量大的應(yīng)用程序中效果最明顯。另外,這些在后臺延遲下載的資源在內(nèi)存緊張時(shí)可以自動刪除,從而極大地提高內(nèi)存的利用率。

8.

什么是Notification?什么時(shí)候用Delegate或Notification?正確答案:Notification(通知)是Cocoa框架中基于觀察者模式實(shí)現(xiàn)的用于一對多傳播消息的一種機(jī)制。項(xiàng)目中的對象將它們自己或者其他對象添加到通知的觀察者列表里(這個過程又叫通知注冊),其中項(xiàng)目中的所有通知都有一個唯一的字符串標(biāo)識作為通知名唯一確定每個通知,通知源也就是被觀察者可以創(chuàng)建通知對象并發(fā)送到通知中心,通知中心找出所有注冊該通知的對象(觀察者),并將從被觀察者那里收到通知以消息的方式發(fā)送給所有的觀察者們。被觀察者發(fā)送通知是一個同步過程,即發(fā)送者在通知中心成功將該發(fā)送者之前的消息發(fā)送給所有觀察者之前不可以再次發(fā)送通知。另外,通知觸發(fā)的代理方法都必須符合某個單一參數(shù)簽名約定,代理方法的參數(shù)是一個通知對象,參數(shù)里包含著通知名、被觀察者和一個包含其他額外信息的字典。

Delegate和Notification的主要區(qū)別在于前者是一對一的消息傳遞,而后者是一對多的,可以根據(jù)這個特點(diǎn)在使用中進(jìn)行選擇。另外在代理模式中,reciever(接收者)可以返回值給sender(發(fā)送者),實(shí)現(xiàn)一種回調(diào),而觀察者模式中觀察者不可以返回值給被觀察者,因此在需要實(shí)現(xiàn)回調(diào)時(shí)只能選擇代理模式。

9.

按照默認(rèn)法則,哪些關(guān)鍵字生成的對象需要手動釋放?正確答案:起初在MRC(手動引用計(jì)數(shù))中開發(fā)者要自己手動管理內(nèi)存,基本原則是:誰創(chuàng)建,誰釋放,誰引用,誰管理。其中,創(chuàng)建主要始于關(guān)鍵詞new、alloc和copy的使用,創(chuàng)建并持有開始引用計(jì)數(shù)為1,如果引用要通過發(fā)送retain消息增加引用計(jì)數(shù),通過發(fā)送release消息減少引用計(jì)數(shù),那么引用計(jì)數(shù)變?yōu)?后對象會被系統(tǒng)清理釋放?,F(xiàn)在有了ARC(自動引用計(jì)數(shù))后編譯器會自動管理引用計(jì)數(shù),開發(fā)者不再需也不可以手動管理引用計(jì)數(shù)。

使用new、alloc、copy關(guān)鍵字生成的對象和retain了的對象需要手動釋放。被設(shè)置為autorelease的對象不需要手動釋放,會直接進(jìn)入自動釋放池。

10.

如何理解HTTP協(xié)議?正確答案:超文本傳輸協(xié)議(HyperTextTransferProtocol,HTTP)是互聯(lián)網(wǎng)上應(yīng)用最為廣泛的一種網(wǎng)絡(luò)協(xié)議。簡單來說,HTTP是客戶端和服務(wù)器端之間請求和應(yīng)答的標(biāo)準(zhǔn),它可以使瀏覽器(或其他客戶端)更加高效,使網(wǎng)絡(luò)傳輸減少。它不僅保證計(jì)算機(jī)正確快速地傳輸超文本文檔,還確定傳輸文檔中的哪一部分,以及哪部分內(nèi)容優(yōu)先顯示(如文本先于圖形)等。

一次HTTP操作稱為一個事務(wù),其工作過程可分為4步:

1)客戶端與服務(wù)器需要建立連接。例如,單擊某個超鏈接后,瀏覽器和服務(wù)器將建立通信連接。

2)建立連接后,客戶端發(fā)送一個請求給服務(wù)器,請求方式的格式為:統(tǒng)一資源標(biāo)識符(URL)、協(xié)議版本號,后邊是MIME信息包括請求修飾符、客戶端信息和可能的內(nèi)容。

3)服務(wù)器接到請求后,給予相應(yīng)的響應(yīng)信息,其格式為一個狀態(tài)行,包括信息的協(xié)議版本號、一個成功或錯誤的代碼,后邊是MIME信息包括服務(wù)器信息、實(shí)體信息和可能的內(nèi)容。

4)客戶端接收服務(wù)器所返回的信啟、通過瀏覽器顯示在用戶的顯示屏上,然后客戶機(jī)與服務(wù)器斷開連接。

如果在以上過程中的某一步出現(xiàn)錯誤,那么產(chǎn)生錯誤的信息將返回到客戶端,由顯示屏輸出。對于用戶來說,這些過程是由HTTP自己完成的,用戶只要用鼠標(biāo)單擊,等待信息顯示就可以了。

通常HTTP消息包括客戶端向服務(wù)器的請求消息和服務(wù)器向客戶端的響應(yīng)消息。這兩種類型的消息由一個起始行,一個或者多個頭域,一個指示頭域結(jié)束的空行和可選的消息體組成。HTTP的頭域包括通用頭、請求頭、響應(yīng)頭和實(shí)體頭4個部分。每個頭域由一個域名、冒號(:)和域值組成。域名是大小寫無關(guān)的,域值前可以添加任何數(shù)量的空格符,頭域可以被擴(kuò)展為多行,在每行開始處,使用至少一個空格或制表符。

一個完整的由客戶端發(fā)給服務(wù)器的HTTP請求包含以下兩部分內(nèi)容。

1)請求頭:包含了對客戶端的環(huán)境描述、客戶端請求信息等。

GET/minion.pngHTTP/1.1

//包含了請求方法、請求資源路徑、HTTP協(xié)議版本

Host:86:32812

//客戶端想訪問的服務(wù)器主機(jī)地址

User-Agent:Mozilla/5.0

//客戶端的類型,客戶端的軟件環(huán)境

Accept:text/html

//客戶端所能接收的數(shù)據(jù)類型

Accept-Language:zh-cn

//客戶端的語言環(huán)境

Accept-Encoding:gzip

//客戶端支持的數(shù)據(jù)壓縮格式

2)請求體:客戶端發(fā)給服務(wù)器的具體數(shù)據(jù),例如文件數(shù)據(jù)(POST請求才會有)。

同樣,一個完整的HTTP響應(yīng)中應(yīng)該包含以下兩部分內(nèi)容。

1)響應(yīng)頭:包含了對服務(wù)器的描述、對返回?cái)?shù)據(jù)的描述。

HTTP/1.1200OK

//包含了HTTP協(xié)議版本、狀態(tài)碼、狀態(tài)英文名稱

Server:Apache-Coyote/1.1

//服務(wù)器的類型

Content-Type:image/jpeg

//返回?cái)?shù)據(jù)的類型

Content-Length:56811

//返回?cái)?shù)據(jù)的長度

Date:Mon,23Jun201412:54:52GMT

//響應(yīng)的時(shí)間

2)響應(yīng)體:服務(wù)器返回給客戶端的具體數(shù)據(jù),例如文件數(shù)據(jù)。

常見的響應(yīng)狀態(tài)碼如圖所示。

常見的響應(yīng)狀態(tài)碼

此外,在iOS開發(fā)中發(fā)送HTTP請求有以下幾種方案:

1)NSURLConnection。iOS7之前,通常使用NSURLConnection及關(guān)聯(lián)類,這是iOS開發(fā)中最經(jīng)典的網(wǎng)絡(luò)請求方案。

2)NSURLSession。iOS7之后,逐漸取代NSURLConnection,現(xiàn)在已經(jīng)是iOS開發(fā)中最常用的網(wǎng)絡(luò)請求方式。

3)CFNetwork。它是NSURLConnection和NSURLSession的底層C語言實(shí)現(xiàn),很少在開發(fā)中使用。

4)其他第三方網(wǎng)絡(luò)請求框架,如Objective-C中的AFNetworking和Swift中的Alamofire等。這些網(wǎng)絡(luò)框架也基本上都是對其他3種方案的封裝與拓展。

11.

什么是Cocoa和CocoaTouch?正確答案:Cocoa和CocoaTouch分別是OSX平臺和。iOS平臺的應(yīng)用開發(fā)環(huán)境,兩個平臺的環(huán)境都包含Objective-C的運(yùn)行時(shí)環(huán)境和Foundation框架。

Cocoa用來開發(fā)OSX系統(tǒng)上的應(yīng)用,它主要包括Foundation框架和AppKit界面開發(fā)框架,如圖所示。

Cocoa架構(gòu)圖

CocoaTouch用來開發(fā)iOS系統(tǒng)上的應(yīng)用(主要指iPhone和iPad),它主要包括Foundation框架和UIKit界面開發(fā)框架,如圖所示。

12.

觸發(fā)器分為事前觸發(fā)和事后觸發(fā),二者有什么區(qū)別?語句級觸發(fā)和行級觸發(fā)有什么區(qū)別?正確答案:事前觸發(fā)發(fā)生在事件發(fā)生之前驗(yàn)證一些條件或進(jìn)行一些準(zhǔn)備工作;事后觸發(fā)發(fā)生在事件發(fā)生之后,做收尾工作,保證事務(wù)的完整性。事前觸發(fā)可以獲得之前和新的字段值。語句級觸發(fā)器可以在語句執(zhí)行之前或之后執(zhí)行,而行級觸發(fā)在觸發(fā)器所影響的每一行觸發(fā)一次。

13.

一般的方法method和Objective-C中的選擇器selector有什么區(qū)別?正確答案:selector是一個方法的名字,基于動態(tài)綁定環(huán)境下;method是一個組合體,包含了名字和實(shí)現(xiàn)。

可以理解@selector()就是取類方法的編號,它的行為基本可以等同C語言的中函數(shù)指針,只不過C語言中,可以把函數(shù)名直接賦給一個函數(shù)指針,而Objective-C的類不能直接應(yīng)用函數(shù)指針,只能通過一個@selector語法來取,它的結(jié)果是一個SEL類型。這個類型本質(zhì)是類方法的編號(函數(shù)地址)。

14.

Objective-C中@class代表什么?正確答案:@class相當(dāng)于只是在頭文件聲明一下要用到的類的頭文件(前向聲明),告訴編譯器有這樣一個類的定義但暫時(shí)不要將類的實(shí)現(xiàn)引入,讓該類定義的變量能夠編譯通過,直到運(yùn)行起來時(shí)才去查看類的實(shí)現(xiàn)文件。但實(shí)際上這樣也只能起到在頭文件中聲明該類實(shí)例變量的作用,在.m文件中如果用到類的實(shí)現(xiàn)細(xì)節(jié)(屬性和方法),那么還是要通過#import再次引入類的頭文件。

使用@class的好處是將頭文件的引入延遲了,至少延遲到了.m實(shí)現(xiàn)文件中,這也符合“直到真正用到的時(shí)候再確定引入”的動態(tài)思想,盡量往后拖延,更重要的是這樣也可以有效地避免頭文件的重復(fù)引入甚至循環(huán)引用等問題。

15.

什么是Layer層對象?正確答案:Layer層對象是用來展示可見內(nèi)容的一種數(shù)據(jù)對象,常在視圖中用來渲染視圖內(nèi)容。一般的層對象在界面中可以實(shí)現(xiàn)一些復(fù)雜的動畫或者其他類型的一些復(fù)雜特效。

常見的幾個其自身具有繪制功能的專用Layer有:CATextLayer、CAShapeLayer、CAGradientLayer,這里給出使用示例。其他還有用于3D圖形變換的CATransformLayer,實(shí)現(xiàn)滾動視圖的CAScrollLayer,專門播放視頻的AVPlayerLayer和制作粒子特效的CAEmitterLayer等。它們都是繼承自CALayer的,和CALayer一樣都來自QuartzCore.framework框架。

1.CATextLayer

這個類是用來實(shí)現(xiàn)更加靈活的文字布局和渲染的,它幾乎包含了UILabe1的所有特性并在此基礎(chǔ)上增加了很多更強(qiáng)大的功能,包括字體、尺寸、前景色和下畫線等文字效果,同時(shí)CATextLayer的渲染效率明顯高于UILabel。

通過CALayer來實(shí)現(xiàn)一個UILabel的示例代碼如下(效果見圖):

-(void)viewDidLoad{

[superviewDidLoad];

/*創(chuàng)建一個字符承載視圖*/

UIView*textView=[[UIViewalloc]initWithFrame:CGRectMake(50,50,200,50)];

CATextLayer*text=[CATextLayerlayer];

text.frame=textView.frame;

text.string=@"CAText";

/*文字前景色和背景色*/

text.foregroundColor=[UIColorwhiteColor].CGColor;

text.backgroundColor=[UIColorblackColor].CGColor;

/*文字超出視圖邊界裁剪*/

text.wrapped=YES;

/*文字字體*/

text.font=(__bridgeCFTypeRef)[UIFontsystemFontOfSize:30].fontName;

/*文字居中*/

text.alignmentMode=kCAAlignmentCenter;

/*適應(yīng)屏幕Retina分辨率,防止像素化導(dǎo)致模糊*/

text.contentsScale=[[UIScreenmainScreen]scale];

[textView.layeraddSublayer:text];

[self.viewaddSubview:textView];

}

CATextLayer效果

2.CAShapeLayer

這個類是用來專門繪制矢量圖形的圖形子類,例如可以指定線寬和顏色等利用CGPath繪制圖形路徑,可以實(shí)現(xiàn)圖形的3D變換效果,渲染效率比CoreGraphics快很多,而且可以在超出視圖邊界之外繪制,即不會被邊界裁減掉。

這里展示使用CAShapeLayer繪制一個圓形的實(shí)例代碼如下(效果見圖):

-(void)viewDidLoad{

[superviewDidLoad];

/*創(chuàng)建圓形路徑*/

UIBezierPath*path=[[UIBezierPathalloc]init];

/*起點(diǎn)要在圓心水平右側(cè)半徑長度處*/

[pathmoveToPoint:CGPointMake(200,100)];

/*添加圓形弧路徑*/

[pathaddAreWithCenter:CGPointMake(150,100)radius:50startAngle:0endAngle:2*M_PIclockwise:YES];

/*創(chuàng)建圖形層*/

CAShapeLayer*layer=[CAShapeLayerlayer];

/*路徑線的顏色*/

layer.strokeColor=[UIColorredColor].CGColor;

/*閉合圖形填充色,這里設(shè)置透明*/

layer.fillColor=[UIColorclearColor].CGColor;

/*線寬*/

layer.lineWidth=10;

/*線的樣式:端點(diǎn)、交點(diǎn)*/

layer.lineCap=kCALineCapRound;

layer.lineJoin=kCALineJoinRound;

/*設(shè)置圖形路徑*/

layer.path=path.CGPath;

[self.view.layeraddSublayer:layer];

}

@end

CAShapeLayer繪制效果

3.CAGradientLayer

它是一個硬件加速的高性能繪制圖層,主要用來實(shí)現(xiàn)多種顏色的平滑漸變效果。這里給出一個3種顏色從正方形左上角到右下角的漸變效果示例代碼(效果見圖6):

-(void)viewDidLoad{

[superviewDidLoad];

/*創(chuàng)建layer承載視圖*/

UIView*containerView=[[UIViewalloc]initWithFrame:CGRectMake(50,50,150,150)];

CAGradientLayer*layer=[CAGradientLayerlayer];

layer.frame=containerView.bounds;

/*依次設(shè)置漸變顏色數(shù)組*/

layer.colors=@[(__bridgeid)[UIColorgreenColor].CGColor,(__bridgeid)[UIColoryellowColor].CGColor,(__bridgeid)[UIColororangeColor].CGColor];

/*顏色從起點(diǎn)到終點(diǎn)按比例分段位置*/

layer.locations=@[@0,0,@0.3,@0.5];

/*顏色漸變的起點(diǎn)和終點(diǎn):(0,0)~(1,1)表示左上角到右下角*/

layer.startPoint=CGPointMake(0,0);

layer.endPoint=CGPointMake(1,1);

[containerView.layeraddSublayer:layer];

[self.viewaddSubview:containerView];

}

CAGradientLayer繪制效果

16.

在Objective-C中,常量有哪幾種類型?正確答案:在Objective-C中,常量有以下4種類型。

(1)整型常量

整型常量由一個或多個int類型數(shù)字的序列組成。值12、0和-10都是合法的整型常量。數(shù)字之間不允許插入空格,并且不能使用逗號等特殊符號(例如,1,000就是一個非法的整型常量,它必須寫作1000)。

(2)浮點(diǎn)型常量

浮點(diǎn)型常量和整型常量的數(shù)據(jù)正好相反,浮點(diǎn)型常量可以存儲包含小數(shù)位數(shù)字的值。例如0.01、3.1415926、-0.002等都是合法的浮點(diǎn)型常量。

(3)字符常量

字符類型的常量可以存儲單個字符。將字符放入一對單引號中就能得到字符常量。因此,“a”“.”“;”和“100”都是合法的字符常量。需要注意的是,第4個表示字符100,它和數(shù)字100并不相同。

(4)符號常量

前面3種常量可統(tǒng)稱為直接常量,而符號常量是使用標(biāo)識符代表一個常量。符號常量在使用之前必須先定義,其一般形式為:

#define標(biāo)識符常量

示例代碼如下:

#definePRICE10

main(){

intnum,total;

num=10;

total=num*PRICE;

printf("total=%d",total);

}

以上程序的輸出為100。在本例中,#define是一條預(yù)處理命令(在后面的預(yù)處理程序章節(jié)中將進(jìn)一步介紹),其功能是將標(biāo)識符定義為其后的常量值。習(xí)慣上符號常量的標(biāo)識符用大寫字母,變量標(biāo)識符用小寫字母,以示區(qū)別。

17.

NSMutableDictionary中setValue和setObject有什么區(qū)別?正確答案:需要了解蘋果公司API中關(guān)于NSMutableDictionary中setValue:forKey:方法和setObject:forKey:方法的定義。其中,對應(yīng)setValue:forKey:方法的API是:

@interfaceNSMutableDictionary<KeyType,ObjectType>(NSKeyValueCoding)

/*Send

-setObject:forKey:tothereceiver,unlessthevalueisnil,inwhichcasesend-removeObjectForKey:*/

-(void)setValue:(nullableObjectType)valueforKey:(NSString*)key;

@end

官方的注釋說得很清楚,當(dāng)發(fā)送setValue:forKey:消息給一個NSMutableDictionary類型的對象時(shí),一般情況下仍然是調(diào)用了setObject:forKey方法,除非,當(dāng)參數(shù)value的值是nil的時(shí)候,就會轉(zhuǎn)而調(diào)用removeObjectForKey:清除這個鍵值對。

對應(yīng)setobject:forKey:方法的API是:

-(void)setObject:(id)anObjectforKey:(id<NSCopying>)aKey;

這里需要注意的是,這個方法中Key是一個遵循了NSCopying協(xié)議的id類型對象,并不是NSString類型的字符串,只不過在實(shí)踐中通常使用NSString而己。示例代碼如下:

NSMutableDictionary*dic=[NSMutableDictionarydictionary];

[dicsetObject:@"1"forKey:[NSNumbernumberWithInt:1]];

[dicsetValue:@"2"forKey:[NSNumbernumberWithInt:2]];

NSLog(@"value1=%@value2=%@",dic[[NSNumbernumberWithInt:1]],dic[[NSNumbernumberWithInt:2]]);

程序的輸出結(jié)果為:

2016-10-1117:12:40:865test[5827:890647]value1=1value2=2

事實(shí)上,當(dāng)試圖為setValue:forKey:設(shè)置一個非NSString類型的Key時(shí)(此處是NSNumber類型),系統(tǒng)會發(fā)出“uncompatiblepointertypessending'NSNumber*_Nonnull'toparameteroftype'NSString*_Nonnull'”的警告,但是不會拋出異常,仍然會正常打印出結(jié)果。

綜上所述,NSMutableDictionary中setValue:forKey:方法和setObject:forKey:方法的主要區(qū)別有:

1)setObject:forKey:方法是NSMutableDictionary類特有的,只有NSMutableDictionary類及其子類的實(shí)例化對象能夠使用,而setValue:forKey:方法是KVC的主要方法,只要遵循了NSCoding協(xié)議的對象都能夠使用。

2)setObject:forKey:方法中參數(shù)value的值不能為nil,否則會拋出異常。而setValue:forKey:中value能夠?yàn)閚il,只是當(dāng)value為nil的時(shí)候,會自動調(diào)用removeObject:forKey:方法。

3)setValue:forKey:中key的參數(shù)只能夠是NSString類型,而setObject:forKey:的key可以是任何類型的對象類型。

18.

Objective-C的類可以多重繼承嗎?可以實(shí)現(xiàn)多個接口嗎?重寫一個類的方式用繼承好還是類別好?為什么?正確答案:Objective-C的類只支持單繼承,不可以多重繼承。

Objective-C可以利用protocol代理協(xié)議實(shí)現(xiàn)多個接口,通過實(shí)現(xiàn)多個接口完成類似C++的多重繼承。在Objective-C中多態(tài)特性是通過protocol(協(xié)議)或者Category(類別)來實(shí)現(xiàn)的。protocol定義的接口方法可以被多個類實(shí)現(xiàn),Category可以在不變動原類的情況下進(jìn)行方法重寫或者擴(kuò)展。

重寫一個類一般情況下使用類別更好,因?yàn)橛肅ategory去重寫類的方法,僅對本Category有效,不會影響到其他類與原有類的關(guān)系。

19.

AppID和BundleID有什么不同?正確答案:AppID是一個組合字符串,它包括兩個部分,一個是開發(fā)團(tuán)隊(duì)的ID,另一個是標(biāo)識應(yīng)用的BundleID,它們之間是用點(diǎn)隔開的。開發(fā)團(tuán)隊(duì)的ID是蘋果公司提供給開發(fā)者的,這個ID可以唯一標(biāo)識一個開發(fā)團(tuán)隊(duì);BundleID是開發(fā)者自定義的唯一標(biāo)識一個應(yīng)用的。一個團(tuán)隊(duì)的ID和不同的BundleID組合可以得到不同的AppID,這個AppID就可以標(biāo)識該團(tuán)隊(duì)的不同的應(yīng)用,開發(fā)者需要通過AppID來使自己的應(yīng)用可以獲取豐富的蘋果服務(wù),如iCloud服務(wù)等。

BundleID也就是AppID的后半部分,是一個App應(yīng)用的唯一標(biāo)識符,

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論