1.UIView 與CALayer的關系
每個UIView內部都有一個CALayer在背后提供內容的繪制和顯示,并且UIView的尺寸樣式都是由內部的layer所提供;
在view顯示的時候,UIView作為layer的CALayerDelegate,view的顯示內容取決于內部的CALayer的display;
最明顯的區別是view可以接受并處理事件,layer不可以
2.self ?super的區別于聯系
self:是關鍵字,代表當前方法的調用者
如果是類方法,則代表當前類;如果是對象方法,則代表當前類的對象
super:編譯器指令
其實不管是self還是super,真正調用的對象都是一樣的,只是查找方法的位置不一樣.self是從當前類結構中開始查找,super是從父類中查找,但方法真正的接受者都是當前類或者當前類的對象.
延伸思考:重寫init方法為什么要用self=[super init]?
[super init]是面向對象的體現,初始化父類的一些屬性;
將[super init]賦給self是為了防止父類的初始化方法release掉了self指向的空間并重新alloc了一塊內存空間,這樣的話[super init] 可能?alloc失敗,導致返回為nil,這時就不再執行if條件語句了
3.@synthesize和@dynamic分別有什么作用?
@property有兩個對應的詞,一個是 @synthesize,一個是 @dynamic。如果 @synthesize和 @dynamic都沒寫,那么默認的就是@syntheszie view = _view;
@synthesize 如果你沒有手動實現 setter 方法和 getter 方法,那么編譯器會自動為你加上這兩個方法。
@dynamic告訴編譯器:屬性的 setter 與 getter 方法由用戶自己實現,不自動生成。(當然對于 readonly 的屬性只需提供 getter 即可).假如一個屬性被聲明為 @dynamic view,然后你沒有提供 @setter方法和 @getter 方法,編譯的時候沒問題,但是當程序運行到?instance.view = someView,由于缺 setter 方法會導致程序崩潰;或者當運行到?someView = view 時,由于缺 getter 方法同樣會導致崩潰。編譯時沒問題,運行時才執行相應的方法,這就是所謂的動態綁定。
4.類擴展?extension,匿名分類,作用:為類添加一些私有成員和方法.
類別Category,也叫分類,作用如下:
a.可以將類的實現分散到多個不同文件或者多個不同框架中,方便代碼管理
b.創建對私有方法的前向引用
c.向對象添加非正式協議
一般情況用分類好,用Category去重寫類的方法,僅對本Category有效,不會影響到其他類與原有類的關系.
5.OC的類可以多重繼承么?可以實現多個接口嗎?
oc不可以多繼承,是單繼承的;可以用協議protocol來實現多個接口,通過實現多個接口來完成多重繼承.
6.用@property聲明的NSString(或NSArray,NSDictionary)經常使用copy關鍵字,為什么?如果改用strong關鍵字,可能造成什么問題?
因為這些類型都有對應的可變類型的子類,他們之間可能進行賦值操作,為保證對象中的字符串值不會被無意中改動,應該在設置新屬性值時拷貝一份.如果使用strong修飾,就有可能指向一個可變對象,如果這個可變對象在外部被修改了,就會影響該屬性.
7.KVO的基本原理
a.kvo是基于runtime機制實現的
b.當某個類的屬性對象第一次被觀察時,系統就會在運行期動態的創建該類的一個派生類,在這個派生類中重寫基類中任何被觀察的屬性的setter方法.派生類在被重寫的setter方法中實現真正的通知機制
c.如果原類是person,那么生成的派生類為NSKVONotifying_Person
d.每個類對象中都有?個isa指針指向當前類,當一個類對象的第一次被觀察,那么系統會偷偷將isa指針指向動態生成的派生類,從?在給被監控屬性賦值時執行的是派生類的setter?方法
e.鍵值觀察通知依賴于NSObject 的兩個?方法: willChangeValueForKey: 和 didChangevlueForKey:;在?個被觀察屬性發?改變之前, willChangeValueForKey:一定會被調用,這就會記錄舊的值。而當改變發生后, didChangeValueForKey:會被調?,繼?而observeValueForKey:ofObject:change:context: 也會被調?
8.objc在向一個對象發送消息時,發生了什么?
objc在向一個對象發送消息時,runtime庫會根據對象的isa指針找到該對象實際所屬的類,然后在該類的方法列表及父類的方法列表中尋找方法運行,然后在發送消息的時候,objc_msgsend方法不會返回值,所謂的返回內容都是具體調用時執行的.
9.runloop是來做什么的?runloop和線程有什么關系?主線程默認開啟了了runloop 么??子線程呢?
runloop:字面意思就是跑圈,其實也就是一個循環跑圈,用來處理線程里邊的事件和消息
runloop和線程的關系:每個線程如果想繼續運行,不被釋放,就必須有一個runloop來不停的跑圈,以來處理線程里面的事件和消息
主線程是默認開啟一個runloop的,子線程默認沒有開啟
10.完整消息轉發機制
第一步:對象收到無法解讀的消息后,首先會調用方法(resolveInstanceMethod或者resolveClassMethod)進行詢問是否有動態添加方法來處理,有就處理,沒有就執行第二步
第二步:沒有新增方法的話,就詢問是否有別的類能幫忙處理(forwardingTargetForSelector),如果有結束,沒有執行最后一步
第三步:調用forwardInvocation,若消息未能處理,則會調用- (void)doesNotRecognizeSelector:(SEL)aSelector,可以在該方法中做文章,避免crash掉.實際開發中,盡量不做處理,讓其拋出異常
11.定時器
NSTimer: 兩種創建方法 ?scheduledTimerWithTimeInterval和timerWithTimeInterval.前者自動啟動,后者需要手動啟動
CADisplayLink:基于屏幕刷新的周期,1/60秒,適合做UI的不停重繪
GCD:GCD定時器是dispatch_source_t類型的變量
12.性能優化http://www.lxweimin.com/p/9220374d6f33
a.tableview優化 :重用標識符的使用;view不透明;減少subview的數量
b.UIImage加載圖片性能優化:如果加載大圖且僅使用一次,使用imageWithContentsOfFile
c.不要在viewwillappear中做耗時操作
d.不要阻塞主線程
e.Instrument優化
13.串行與并行/異步與同步? ?并發與并行的區別
隊列分為串行與并行;任務的執行分為同步和異步;隊列只負責任務的調度,不負責任務的執行
區別:并發和并?是即相似?有區別的兩個概念,并?是指兩個或者多個事件在同一時刻發?;?并發是指兩個或多個事件在同一時間間隔內發?。在多道程序環境下, 并發性是指在一段時間內宏觀上有多個程序在同時運?,但在單處理理機系統中,每一 時刻卻僅能有一道程序執?,故微觀上這些程序只能是分時地交替執?。倘若在計算 機系統中有多個處理機,則這些可以并發執?的程序便便可被分配到多個處理理機上,實現并行執?,即利用每個處理理機來處理一個可并發執?的程序,這樣,多個程序便以同時執?。
14.線程和進程
一個程序至少有一個進程,一個進程至少有一個線程,進程有自己獨立的內存單元,線程是進程的基本組成單元.
15.談談多線程的理解?ios有幾種方法實現多線程
好處:可以把占據時間長的程序中的任務放到后臺去處理,提高程序的運行速度;
壞處:如果有大量的線程會影響性能,因為操作系統需要在他們之間切換;
16.內存管理原則
遵循“誰創建誰釋放,誰引用誰管理”的機制,當創建或引用一個對象的時候,需要向他發送alloc、copy、retain消息,當釋放該對象時需要發送release消息,當對象引用計數為0時,系統將釋放該對象,這是OC的手動管理機制(MRC)。iOS5.0之后引用自動管理機制(ARC),管理機制與手動管理機制一樣,只是不再需要調用retain、release、autorelease;它是編譯時特性,當使用ARC時,在適當的位置插入release和autorelease;它引用strong和weak關鍵字,strong修飾的指針變量指向對象時,當指針指向新值或者指針不存在時,相關聯的對象就會自動釋放,而weak修飾的指針變量指向對象,當指針的擁有者指向新值或者不存在時weak修飾的指針會自動置為nil。
17.dispatch_barrier_async的作用是什么?
在并行隊列中,為了保證某些任務的順序,需要等待一些任務完成后才能繼續進行,使?barrier 來等待之前任務完成,避免數據競爭等問題
18.如何?用GCD同步若?個異步調用?(如根據若干個url異步加載多張圖片,然后在都下載完成后合成一張整圖)
使?用Dispatch Group追加block到Global Group Queue,這些block如果全部執行完畢,就會執行Main Dispatch Queue中的結束處理理的block.
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);?
dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group, queue, ^{ /*加載圖?片1 */ });
?dispatch_group_async(group, queue, ^{ /*加載圖?片2 */ });?
dispatch_group_async(group, queue, ^{ /*加載圖?片3 */ });
?dispatch_group_notify(group, dispatch_get_main_queue(), ^{// 合并圖?片 });
19. isKindOfClass與isMemberOfClass的區別
isKindOfClass:確定一個對象是否是一個類的成員,或者是該類的子類成員
isMemberOfClass:只能確定一個對象是否是當前類的成員.
比如AString繼承自NSString,那么如果用 [AString的成員 isKindOfClass:[NSString class]] 返回的是YES,使用isMemberOfClass返回的是NO。
20.IAP內購中虛擬貨幣導致審核?法通過的問題?
有的時候需要在app中使用虛擬貨幣,在我們的app中可以使?用虛擬貨幣進行購買道具 等,比如直播中的禮物,游戲中的道具等。
蘋果對于虛擬貨幣是需要提成的,提成的額度為30%。所以對于這塊的審核?比較嚴 格。?首先你們的購買的道具在ios端和安卓端是需要分開的。如果?家玩游戲的就會發現游戲的數據在兩端是分開的。 ?戶在安卓?機上購買的道具在ios上不能使用。因為這樣也間接的影響了了蘋果的收入。
另外就是在審核期間不能有可以兌換在appStore可購買的商品的任意活動或者 換碼,這個也是蘋果不允許的。因為這個也會影響蘋果的收?。
另外就是可能有人會在蘋果審核之后隱藏ipa?支付,此處提醒下,蘋果會掃描你的app代碼中是否有?支付寶,微信等關于支付的字段。使?開關加h5的?式可以通過審核,但是此處也有?險,風險就是?一旦被發現,可能的結果就是蘋果直接封掉賬號。app?法使?
21.野指針和空指針
只要一個對象被釋放了,我們就稱這個對象為僵尸對象(不能再使用的對象);當一個指針指向一個僵尸對象,我們就稱這個指針為野指針;只要給一個野指針發送消息就會報錯;
空指針:沒有指向內存空間的指針(里面存的是nil,也就是0),給空指針發消息是沒有任何反應的
22.atomic ?nonatomic
a.atomic和nonatomic用來決定編譯器生成的getter和setter是否為原子操作
b.atomic所說的線程安全只是保證了getter和setter存取方法的線程安全,并不能保證整個對象是線程安全的
23.NSTimer 定期器準嗎?為什么不準?如何優化的?
不準;
原因:
a.runloop的影響,如果加入的runloop中做了耗時操作,當前runloop的持續時間超過了定時器的間隔時間,那么下一次定時就會被延后;
b.runloop模式的影響
24.assign ?vs weak?
?__block vc __weak?
assign適用于基本數據類型,weak適用于NSObject對象,并且是一個弱引用;assign其實也可以用來修飾對象,但是因為被assign修飾的對象在釋放之后,指針的地址還是存在的,也就是說指針并沒有被置為nil,如果在后續的內存分配中,剛好分到了這塊地址,程序就會崩潰;而weak修飾的對象在釋放之后,指針地址被置為nil.
延伸問題:實現weak后,為什么對象釋放后會自動置為nil?
runtime對注冊的類會進行布局,對于weak對象會放入一個哈希表中,用weak指向的對象的內存地址作為key,當此對象的引用計數為0的時候會dealloc.假如weak指向的對象內存地址是a,那么就會以a為鍵,在這個weak表中搜索,找到所有以a為鍵的weak對象,從而置為nil
25.為什么被__block修飾的變量可以在block內部被修改?
block不允許修改外部變量的值,這里所說的外部變量的值指的是棧中指針的內存地址,__block的作用其實就是在堆上創建一個指向棧變量的指針達到修改棧變量值的目的。
26. alloc ?init ?new
alloc:分配內存
init:初始化
new:代替上邊兩個函數,分配內存并初始化
alloc分配內存的時候使用了zone,他是給對象分配內存的時候,把關聯的對象分配到一個相鄰的內存區域內,以便于調用時耗費很好的內存,提升了程序處理速度
不推薦new:因為沒辦法定制其他初始化方法
27.initialize和load的區別
load是只要類所在文件被引用就會被調用,而initialize是在類或者其子類的第一個方法被調用前調用。所以如果類沒有被引用進項目,就不會有load調用;但即使類文件被引用進來,但是沒有使用,那么initialize也不會被調用。
28.如何高性能的給UIImageView加個圓角?
a.用UIGraphics和貝塞爾曲線
+ (UIImage*)drawCircleImageWithImage:(UIImage*)image circleRect:(CGRect)rect {
? ? //開啟上下文
? ? UIGraphicsBeginImageContextWithOptions(image.size, NO, [UIScreen mainScreen].scale);
? ? //設置裁剪區域
? ? UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:rect];//圓形
? ? [pathaddClip];//添加剪切路徑
?? ?//繪制圖片
?? ?[imagedrawAtPoint:CGPointZero];
? ? ? ? //獲取圖片
? ? UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
? ? //關閉上下文
? ? UIGraphicsEndImageContext();
? ? returnnewImage;
}
b.貝塞爾曲線和CAShapeLayer
- (void)corner{
? ? CGRect bounds = self.bounds;
? ? UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:bounds byRoundingCorners:UIRectCornerBottomLeft cornerRadii:CGSizeMake(20,20)];
? ? CAShapeLayer *maskLayer = [CAShapeLayer layer];
? ? maskLayer.frame = bounds;
? ? maskLayer.path = maskPath.CGPath;
? ? [self.layer addSublayer:maskLayer];
? ? self.layer.mask = maskLayer;
}
29.block
在 Objective-C 語言中,一共有 3 種類型的 block:
_NSConcreteGlobalBlock 全局的靜態 block,不會訪問任何外部變量。
_NSConcreteStackBlock 保存在棧中的 block,當函數返回時會被銷毀。
_NSConcreteMallocBlock 保存在堆中的 block,當引用計數為 0 時會被銷毀。
30.加密解密
rsa加密算法 ?非對稱!!!
aes加密算法 ?對稱
31.TCP ?UDP?
都是網絡傳輸層的協議,TCP提供可靠的數據連接,是面向連接的一對一通信;速度慢
udp提供不可靠的數據連接,是廣播式通信,一對多的方式,不會對數據包的順序,是否丟失進行校驗,如果丟失了也不會重新發送,速度快
32.分類里為什么不能添加屬性?
在分類里使用@property聲明屬性,只是將該屬性添加到該類的屬性列表,并聲明了setter和getter方法,但是并沒有生成相應的成員變量,也沒有實現setter和getter方法,所以說分類不能添加屬性.
33.struct和class的區別
struct是一種數據結構的實現體,默認的數據訪問控制是public;而class作為對象的實現體,默認的成員變量訪問控制是私有的。
34.APNS推送機制
a.應用程序的服務器端把要發送的消息/目的iPhone的標識打包發給APNS;
b.APNS在自身已經注冊的push服務的iPhone列表中,查找相應標識的iPhone,并把消息發送到iPhone
c.iPhone把發來的消息傳遞給相應的應用程序,并且按照設定彈出push彈窗
35.HTTPS和HTTP的區別
a.https協議需要到ca申請證書
b.http超文本傳輸協議,信息是明文傳輸,https則是具有安全性的ssl加密傳輸協議
c.兩者端口不同,前者是443,后者是80
36.runtime
運行時機制:最主要的是消息機制,在編譯階段oc可以調用任何函數,即使該函數并未實現,只要生命過就不會報錯,只有在真正運行的時候才會根據函數的名稱找到對應的函數來調用. 比如一個對象A調用一個函數[A test],首先runtime會將oc代碼通過objc_msgSend轉化成objc_msgSend(A,@selector(test));然后通過A對象的isa指針找到對應的類,在類中先去緩存中查找對應的函數,若沒找到,就去方法列表中查找,若還是沒找到就去父類中找,若能找到就加入到緩存中,供下次查找,并執行相應的函數,若父類中也沒找到則crash.
37.信號量
就是一種可用來控制訪問資源的數量的標識,設定了一個信號量,在線程訪問之前,加上信號量的處理,則可告知系統按照我們指定的信號量數量來執行多個線程.
dispatch_semaphore信號量為基于計數器的一種多線程同步機制。用于解決在多個線程訪問共有資源時候,會因為多線程的特性而引發數據出錯的問題
38.響應式編程(Functional Reactive Programming:FRP)
響應式編程是一種和事件流有關的變成模式,關注導致狀態值改變的行為事件,一系列事件組成了事件流. ?一系列事件流導致屬性發生變化的原因,響應式編程類似于設計模式里的觀察者模式.
39.觸摸事件的傳遞與響應
傳遞:從父控件傳遞到子控件,即UIApplication->UIWindow->尋找處理事件最合適的view,如果父控件不能接受觸摸事件,那么子控件就不可能收到觸摸事件
pointInside:withEvent:方法判斷點在不在當前view上(方法調用者的坐標系上)如果返回YES,代表點在方法調用者的坐標系上;返回NO代表點不在方法調用者的坐標系上,那么方法調用者也就不能處理事件
事件的傳遞和響應的區別:事件的傳遞是從上到下(父控件到子控件),事件的響應是從下到上(順著響應者鏈條向上傳遞:子控件到父控件).
40.類方法和實例方法的本質區別
元類是類對象的類
類方法是在這個類的元類的方法列表中查找,實例方法是在這個對象的類的方法列表中查找
41.提升編譯速度
a.將Debug Information Format改為DWARF
在工程對應Target的Build Settings中,找到Debug Information Format這一項,將Debug時的DWARF with dSYM file改為DWARF。
這一項設置的是是否將調試信息加入到可執行文件中,改為DWARF后,如果程序崩潰,將無法輸出崩潰位置對應的函數堆棧,但由于Debug模式下可以在XCode中查看調試信息,所以改為DWARF影響并不大。這一項更改完之后,可以大幅提升編譯速度
b.將Build Active Architecture Only改為Yes
在工程對應Target的Build Settings中,找到Build Active Architecture Only這一項,將Debug時的No改為Yes。
這一項設置的是是否僅編譯當前架構的版本,如果為No,會編譯所有架構的版本。需要注意的是,此選項在Release模式下必須為Yes,否則發布的ipa在部分設備上將不能運行。這一項更改完之后,可以顯著提高編譯速度
42.main函數
a.動態鏈接庫 (系統framework)
b.ImageLoader加載可執行文件, 里邊是被編譯過的符號,代碼等
c.runtime初始化 + load
43.autoreleasepool
自動釋放池用來存放那些需要在稍后的某個時刻釋放的對象.
autoreleasepool是在runloop即將進入時創建,以及即將休眠時銷毀的.
當自動釋放池被銷毀的時候,在池中的對象會自動調用release方法來釋放資源,銷毀對象
44.http通信
a.請求 ?http協議規定:1個完整的有客服端發送給服務器的http請求中包含以下內容?
請求行:包含了請求方法,請求資源路徑,http協議版本?GET /MJServer/resources/images/1.jpg HTTP/1.1
請求頭:包含了對客戶端環境的描述,客戶端請求的主機地址等信息,
Host: 192.168.1.105:8080?// 客戶端想訪問的服務器主機地址
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9) Firefox/30.0// 客戶端的類型,客戶端的軟件環境
Accept: text/html, */*// 客戶端所能接收的數據類型
Accept-Language: zh-cn?// 客戶端的語言環境
Accept-Encoding: gzip?// 客戶端支持的數據壓縮格式
請求體:客戶端發送給服務器的具體數據,比如文件數據
b.響應 ?客戶端向服務器發送請求,服務器應當做出響應,即返回數據給客戶端
狀態行:包含了http協議版本,狀態碼,狀態英文名稱 ?HTTP/1.1 200 OK
響應頭:包含了對服務器的描述,對返回數據的描述
Server: Apache-Coyote/1.1?// 服務器的類型
Content-Type: image/jpeg?// 返回數據的類型
Content-Length: 56811?// 返回數據的長度
Date: Mon, 23 Jun 2014 12:54:52 GMT?// 響應的時間
實體內容:服務器返回給客戶端的具體數據,比如文件數據
45.?JSPatch 的原理就是
JS傳遞字符串給OC,OC通過 Runtime 接口調用和替換OC方法
46.NSMethodSignature和NSInvocation配合用來進行最后的消息轉發
NSMethodSignature對方法的參數、返回值類型進行封裝,協同NSInvocation實現消息轉發;用于獲取參數的個數和方法的返回值
NSInvocation用來包裝方法和對應的對象,它可以存儲方法的名稱,對應的對象,對應的參數,target.?對象設置的參數個數及類型和獲取的返回值的類型要與創建對象時使用的NSMethodSignature對象代表的參數及返回值類型向一致,否則crash。