序言
目前形勢,參加到iOS隊伍的人是越來越多心墅,甚至已經(jīng)到供過于求了酿矢。今年,找過工作人可能會更深刻地體會到今年的就業(yè)形勢不容樂觀怎燥,加之瘫筐,培訓(xùn)機構(gòu)一火車地向用人單位輸送iOS開發(fā)人員,打破了生態(tài)圈的動態(tài)平衡铐姚。矯情一下严肪,言歸正傳,我奉獻一下谦屑,為iOS應(yīng)聘者梳理一下面試題,希望能助一臂之力!
OC的理解與特性
- OC作為一門面向?qū)ο蟮恼Z言篇梭,自然具有面向?qū)ο蟮恼Z言特性:封裝氢橙、繼承、多態(tài)恬偷。它既具有靜態(tài)語言的特性(如C++)悍手,又有動態(tài)語言的效率(動態(tài)綁定、動態(tài)加載等)袍患√箍担總體來講,OC確實是一門不錯的編程語言诡延,
- Objective-C具有相當多的動態(tài)特性滞欠,表現(xiàn)為三方面:動態(tài)類型(Dynamic typing)、動態(tài)綁定(Dynamic binding)和動態(tài)加載(Dynamic loading)肆良。動態(tài)——必須到運行時(run time)才會做的一些事情筛璧。
-
動態(tài)類型
:即運行時再決定對象的類型逸绎,這種動態(tài)特性在日常的應(yīng)用中非常常見,簡單來說就是id類型夭谤。事實上棺牧,由于靜態(tài)類型的固定性和可預(yù)知性,從而使用的更加廣泛朗儒。靜態(tài)類型是強類型颊乘,而動態(tài)類型屬于弱類型纲爸,運行時決定接受者颓哮。 -
動態(tài)綁定
:基于動態(tài)類型姨伤,在某個實例對象被確定后,其類型便被確定了,該對象對應(yīng)的屬性和響應(yīng)消息也被完全確定嫂拴。 -
動態(tài)加載
:根據(jù)需求加載所需要的資源罪裹,最基本就是不同機型的適配冯袍,例如,在Retina設(shè)備上加載@2x的圖片,而在老一些的普通蘋設(shè)備上加載原圖傲隶,讓程序在運行時添加代碼模塊以及其他資源,用戶可根據(jù)需要加載一些可執(zhí)行代碼和資源馋劈,而不是在啟動時就加載所有組件机断,可執(zhí)行代碼可以含有和程序運行時整合的新類。
簡述內(nèi)存管理基本原則
- 之前:OC內(nèi)存管理遵循“誰創(chuàng)建蛾狗,誰釋放,誰引用求冷,誰管理”的機制,當創(chuàng)建或引用一個對象的時候年柠,需要向她發(fā)送alloc渴丸、copy、retain消息罢吃,當釋放該對象時需要發(fā)送release消息,當對象引用計數(shù)為0時,系統(tǒng)將釋放該對象夸赫,這是OC的手動管理機制(MRC)。
- 目前:iOS 5.0之后引用自動管理機制——自動引用計數(shù)(ARC)咖城,管理機制與手動機制一樣茬腿,只是不再需要調(diào)用retain、release宜雀、autorelease切平;它編譯時的特性,當你使用ARC時辐董,在適當位置插入release和autorelease悴品;它引用strong和weak關(guān)鍵字,strong修飾的指針變量指向?qū)ο髸r简烘,當指針指向新值或者指針不復(fù)存在苔严,相關(guān)聯(lián)的對象就會自動釋放,而weak修飾的指針變量指向?qū)ο蠊屡欤攲ο蟮膿碛姓咧赶蛐轮祷蛘卟淮嬖跁rweak修飾的指針會自動置為nil届氢。
- 如果使用
alloc
、copy(mutableCopy)
或者retian
一個對象時,你就有義務(wù),向它發(fā)送一條release
或者autorelease
消息覆旭。其他方法創(chuàng)建的對象,不需要由你來管理內(nèi)存退子。 - 向一個對象發(fā)送一條
autorelease
消息,這個對象并不會立即銷毀, 而是將這個對象放入了自動釋放池,待池子釋放時,它會向池中每一個對象發(fā)送 一條release
消息,以此來釋放對象. - 向一個對象發(fā)送
release
消息,并不意味著這個對象被銷毀了,而是當這個對象的引用計數(shù)為0時,系統(tǒng)才會調(diào)用dealloc
方法,釋放該對象和對象本身它所擁有的實例。
其他注意事項
- 如果一個對象有一個_strong類型的指針指向著姐扮,找個對象就不會被釋放絮供。如果一個指針指向超出了它的作用域,就會被指向nil茶敏。如果一個指針被指向nil壤靶,那么它原來指向的對象就被釋放了。當一個視圖控制器被釋放時惊搏,它內(nèi)部的全局指針會被指向nil贮乳。用法“:不管全局變量還是局部變量用_strong描述就行。
- 局部變量:出了作用域恬惯,指針會被置為nil向拆。
- 方法內(nèi)部創(chuàng)建對象,外部使用需要添加_autorelease;
- 連線的時候酪耳,用_weak描述浓恳。
- 代理使用unsafe_unretained就相當于assign刹缝;
- block中為了避免循環(huán)引用問題,使用_weak描述颈将;
- 聲明屬性時梢夯,不要以
new
開頭。如果非要以new
開頭命名屬性的名字晴圾,需要自己定制get方法名颂砸,如
@property(getter=theString) NSString * newString; - 如果要使用自動釋放池,用
@autoreleasepool{}
- ARC只能管理Foundation框架的變量死姚,如果程序中把Foundation中的變量強制換成COre Foundation中的變量需要交換管理權(quán)人乓;
- 在非ARC工程中采用ARC去編譯某些類:-fobjc-arc。
- 在ARC下的工程采用非ARC去編譯某些類:-fno-fobjc-arc都毒。
如何理解MVC設(shè)計模式
MVC是一種架構(gòu)模式色罚,M表示MOdel,V表示視圖View温鸽,C表示控制器Controller:
- Model負責(zé)存儲保屯、定義、操作數(shù)據(jù)涤垫;
- View用來展示書給用戶姑尺,和用戶進行操作交互;
- Controller是Model和View的協(xié)調(diào)者蝠猬,Controller把Model中的數(shù)據(jù)拿過來給View用切蟋。Controller可以直接與Model和View進行通信,而View不能和Controller直接通信榆芦。View與Controller通信需要利用代理協(xié)議的方式柄粹,當有數(shù)據(jù)更新時,MOdel也要與Controller進行通信匆绣,這個時候就要用Notification和KVO驻右,這個方式就像一個廣播一樣,MOdel發(fā)信號崎淳,Controller設(shè)置監(jiān)聽接受信號堪夭,當有數(shù)據(jù)更新時就發(fā)信號給Controller,Model和View不能直接進行通信拣凹,這樣會違背MVC設(shè)計模式森爽。
如何理解MVVM設(shè)計模式
-
ViewModel
層,就是View和Model層的粘合劑嚣镜,他是一個放置用戶輸入驗證邏輯爬迟,視圖顯示邏輯,發(fā)起網(wǎng)絡(luò)請求和其他各種各樣的代碼的極好的地方菊匿。說白了付呕,就是把原來ViewController
層的業(yè)務(wù)邏輯和頁面邏輯等剝離出來放到ViewModel層计福。 - View層,就是ViewController層徽职,他的任務(wù)就是從ViewModel層獲取數(shù)據(jù)棒搜,然后顯示。
- 如需了解更多活箕,請查看這篇文章
**Objective-C **中是否支持垃圾回收機制?
- OC是支持垃圾回收機制的(
Garbage collection
簡稱GC
),但是apple的移動終端中,是不支持GC的,Mac桌面系統(tǒng)開發(fā)中是支持的. - 移動終端開發(fā)是支持ARC(
Automatic Reference Counting
的簡稱),ARC是在IOS5之后推出的新技術(shù),它與GC的機制是不同的可款。我們在編寫代碼時, 不需要向?qū)ο蟀l(fā)送release
或者autorelease
方法,也不可以調(diào)用delloc
方法,編譯器會在合適的位置自動給用戶生成release
消息(autorelease
),ARC 的特點是自動引用技術(shù)簡化了內(nèi)存管理的難度.
協(xié)議的基本概念和協(xié)議中方法默認為什么類型
OC中的協(xié)議是一個方法列表,且多少有點相關(guān)育韩。它的特點是可以被任何類使用(實現(xiàn)),但它并不是類(這里我們需要注意),自身不會實現(xiàn)這樣方法, 而是又其他人來實現(xiàn)協(xié)議經(jīng)常用來實現(xiàn)委托對象(委托設(shè)計模式)。如果一個類采用了一個協(xié)議,那么它必須實現(xiàn)協(xié)議中必須需要實現(xiàn)的方法,在協(xié)議中的方法默認是必須實現(xiàn)(@required),添加關(guān)鍵字@optional,表明一旦采用該協(xié)議,這些“可選”的方法是可以選擇不實現(xiàn)的闺鲸。
簡述類目category
優(yōu)點和缺點
優(yōu)點:
- 不需要通過增加子類而增加現(xiàn)有類的行為(方法),且類目中的方法與原始類方法基本沒有區(qū)別;
- 通過類目可以將龐大一個類的方法進行劃分,從而便于代碼的日后的維護筋讨、更新以及提高代碼的閱讀性;
缺點:
- 無法向類目添加實例變量,如果需要添加實例變量,只能通過定義子類的方式;
- 類目中的方法與原始類以及父類方法相比具有更高優(yōu)先級,如果覆蓋父類的方法,可能導(dǎo)致
super
消息的斷裂。因此,最好不要覆蓋原始類中的方法摸恍。
類別的作用
- 給系統(tǒng)原有類添加方法悉罕,不能擴展屬性。如果類別中方法的名字跟系統(tǒng)的方法名一樣立镶,在調(diào)用的時候類別中的方法優(yōu)先級更高壁袄;
- 分散類的實現(xiàn):如:
+ (NSIndexPath *)indexPathForRow:(NSInteger)row
inSection:(NSInteger)section
原本屬于NSIndexPath的方法,但因為這個方法經(jīng)常使用的表的時候調(diào)用媚媒、跟表的關(guān)系特別密切嗜逻,因此把這個方法一類別的形式、聲明在UITableView.h中缭召。 - 聲明私有方法栈顷,某一個方法只實現(xiàn),不聲明嵌巷,相當于私有方法萄凤。
- 類別不能聲明變量,類別不可以直接添加屬性搪哪。
property
描述setter方法靡努,就不會報錯。
循環(huán)引用的產(chǎn)生原因噩死,以及解決方法
- 產(chǎn)生原因:如下圖所示颤难,對象A和對象B相互引用了對方作為自己的成員變量,只有自己銷毀的時候才能將成員變量的引用計數(shù)減1已维。對象A的銷毀依賴于對象B的銷毀行嗤,同時對象B銷毀也依賴與對象A的銷毀,從而形成循環(huán)引用垛耳,此時栅屏,即使外界沒有任何指針訪問它飘千,它也無法釋放。
多個對象間依然會存在循環(huán)引用問題栈雳,形成一個環(huán)护奈,在編程中,形成的環(huán)越大越不容易察覺哥纫,如下圖所示:
解決方法:
- 事先知道存在循環(huán)引用的地方霉旗,在合理的位置主動斷開一個引用,是對象回收蛀骇;
- 使用弱引用的方法厌秒。
鍵路徑(keyPath)、鍵值編碼(KVC)擅憔、鍵值觀察(KVO)
** 鍵路徑 **
- 在一個給定的實體中,同一個屬性的所有值具有相同的數(shù)據(jù)類型鸵闪。
- 鍵-值編碼技術(shù)用于進行這樣的查找—它是一種間接訪問對象屬性的機制。 - 鍵路徑是一個由用點作分隔符的鍵組成的字符串,用于指定一個連接在一起的對象性質(zhì)序列暑诸。第一個鍵的性質(zhì)是由先前的性質(zhì)決定的,接下來每個鍵的值也是相對于其前面的性質(zhì)蚌讼。
- 鍵路徑使您可以以獨立于模型實現(xiàn)的方式指定相關(guān)對象的性質(zhì)。通過鍵路徑,您可以指定對象圖中的一個任意深度的路徑,使其指向相關(guān)對象的特定屬性个榕。
** 鍵值編碼KVC**
- 鍵值編碼是一種間接訪問對象的屬性使用字符串來標識屬性篡石,而不是通過調(diào)用存取方法,直接或通過實例變量訪問的機制西采,非對象類型的變量將被自動封裝或者解封成對象夏志,很多情況下會簡化程序代碼;
- KVC的缺點:一旦使用 KVC 你的編譯器無法檢查出錯誤,即不會對設(shè)置的鍵苛让、鍵路徑進行錯誤檢查,且執(zhí)行效率要低于合成存取器方法和自定的 setter 和 getter 方法沟蔑。因為使用 KVC 鍵值編碼,它必須先解析字符串,然后在設(shè)置或者訪問對象的實例變量。
鍵值觀察KVO
- 鍵值觀察機制是一種能使得對象獲取到其他對象屬性變化的通知 狱杰,極大的簡化了代碼瘦材。
- 實現(xiàn) KVO 鍵值觀察模式,被觀察的對象必須使用 KVC 鍵值編碼來修 改它的實例變量,這樣才能被觀察者觀察到。因此,KVC是KVO的基礎(chǔ)仿畸。
Demo
比如我自定義的一個button
[self addObserver:self forKeyPath:@"highlighted" options:0 context:nil];
#pragma mark KVO
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"highlighted"] ) {
[self setNeedsDisplay];
}
}
對于系統(tǒng)是根據(jù)keypath去取的到相應(yīng)的值發(fā)生改變食棕,理論上來說是和kvc機制的道理是一樣的。
KVC機制通過key
找到value
的原理
- 當通過KVC調(diào)用對象時错沽,比如:
[self valueForKey:@”someKey”]
時簿晓,程序會自動試圖通過下面幾種不同的方式解析這個調(diào)用。 - 首先查找對象是否帶有
someKey
這個方法千埃,如果沒找到憔儿,會繼續(xù)查找對象是否帶有someKey
這個實例變量(iVar
)呕屎,如果還沒有找到榆俺,程序會繼續(xù)試圖調(diào)用-(id) valueForUndefinedKey:
這個方法卖氨。如果這個方法還是沒有被實現(xiàn)的話酬屉,程序會拋出一個NSUndefinedKeyException
異常錯誤。 - 補充:KVC查找方法的時候蜈缤,不僅僅會查找someKey這個方法拾氓,還會查找getsomeKey這個方法,前面加一個get底哥,或者_someKey以_getsomeKey這幾種形式咙鞍。同時,查找實例變量的時候也會不僅僅查找someKey這個變量趾徽,也會查找_someKey這個變量是否存在奶陈。
- 設(shè)計
valueForUndefinedKey:
方法的主要目的是當你使用-(id)valueForKey
方法從對象中請求值時,對象能夠在錯誤發(fā)生前附较,有最后的機會響應(yīng)這個請求。
在 **Objective-C **中如何實現(xiàn) KVO
-
注冊觀察者(
注意:觀察者和被觀察者不會被保留也不會被釋放
)- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;
接收變更通知
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object change:(NSDictionary *)change context:(void *)context;移除對象的觀察者身份
- (void)removeObserver:(NSObject *)observer
forKeyPath:(NSString *)keyPath;KVO中
誰要監(jiān)聽誰注冊
潦俺,然后對響應(yīng)進行處理拒课,使得觀察者與被觀察者完全解耦。KVO只檢測類中的屬性事示,并且屬性名都是通過NSString來查找早像,編譯器不會檢錯和補全,全部取決于自己肖爵。
代理的作用
- 代理又叫委托卢鹦,是一種設(shè)計模式,代理是對象與對象之間的通信交互劝堪,代理解除了對象之間的耦合性冀自。
- 改變或傳遞控制鏈。允許一個類在某些特定時刻通知到其他類秒啦,而不需要獲取到那些類的指針熬粗。可以減少框架復(fù)雜度余境。
- 另外一點驻呐,代理可以理解為java中的回調(diào)監(jiān)聽機制的一種類似。
- 代理的屬性常是
assign
的原因:防止循環(huán)引用,以至對象無法得到正確的釋放芳来。
NSNotification含末、Block、Delegate和KVO的區(qū)別
- 代理是一種回調(diào)機制即舌,且是一對一的關(guān)系佣盒,通知是一對多的關(guān)系,一個對向所有的觀察者提供變更通知顽聂;
- 效率:Delegate比NSNOtification高沼撕;
- Delegate和Block一般是一對一的通信宋雏;
- Delegate需要定義協(xié)議方法,代理對象實現(xiàn)協(xié)議方法务豺,并且需要建立代理關(guān)系才可以實現(xiàn)通信磨总;
- Block:Block更加簡潔,不需要定義繁瑣的協(xié)議方法笼沥,但通信事件比較多的話蚪燕,建議使用Delegate;
Objective-C中可修改和不可以修改類型
- 可修改不可修改的集合類奔浅,就是可動態(tài)添加修改和不可動態(tài)添加修改馆纳。
- 比如
NSArray
和NSMutableArray
,前者在初始化后的內(nèi)存控件就是固定不可變的,后者可以添加等汹桦,可以動態(tài)申請新的內(nèi)存空間
當我們調(diào)用一個靜態(tài)方法時,需要對對象進行 **release **嗎?
- 不需要,靜態(tài)方法(類方法)創(chuàng)建一個對象時,對象已被放入自動釋放池鲁驶。在自動釋放池被釋放時,很有可能被銷毀。
當我們釋放我們的對象時,為什么需要調(diào)用[super dealloc]方法,它的位置又是如何的呢?
- 因為子類的某些實例是繼承自父類的,因此需要調(diào)用
[super dealloc]
方法, 來釋放父類擁有的實例,其實也就是子類本身的舞骆。一般來說我們優(yōu)先釋放子類擁 有的實例,最后釋放父類所擁有的實例钥弯。
對謂詞的認識
- Cocoa 中提供了一個
NSPredicate
的類,該類主要用于指定過濾器的條件, 每一個對象通過謂詞進行篩選,判斷條件是否匹配。如果需要了解使用方法督禽,請看謂詞的具體使用
static脆霎、self、super關(guān)鍵字的作用
- 函數(shù)體內(nèi)
static
變量的作用范圍為該函數(shù)體狈惫,不同于auto
變量睛蛛,該變量的內(nèi)存只被分配一次,因此其值在下次調(diào)用時仍維持上次的值. - 在模塊內(nèi)的
static
全局變量可以被模塊內(nèi)所用函數(shù)訪問胧谈,但不能被模塊外其它函數(shù)訪問. - 在模塊內(nèi)的
static
函數(shù)只可被這一模塊內(nèi)的其它函數(shù)調(diào)用忆肾,這個函數(shù)的使用范圍被限制在聲明. - 在類中的
static
成員變量屬于整個類所擁有,對類的所有對象只有一份拷貝. - self:當前消息的接收者菱肖。
- super:向父類發(fā)送消息难菌。
#include與#import的區(qū)別、**#import **與@class 的區(qū)別
-
#include
和#import
其效果相同,都是查詢類中定義的行為(方法); -
#import
不會引起交叉編譯,確保頭文件只會被導(dǎo)入一次蔑滓; -
@class
的表明,只定 義了類的名稱,而具體類的行為是未知的,一般用于.h 文件郊酒; -
@class
比#import
編譯效率更高。 - 此外
@class
和#import
的主要區(qū)別在于解決引用死鎖的問題键袱。
@public燎窘、@protected、@private 它們的含義與作用
-
@public
:對象的實例變量的作用域在任意地方都可以被訪問 ; -
@protected
:對象的實例變量作用域在本類和子類都可以被訪問 ; -
@private
:實例變量的作用域只能在本類(自身)中訪問 .
解釋 **id **類型
任意類型對象蹄咖,程序運行時才決定對象的類型褐健。
**switch **語句 **if **語句區(qū)別與聯(lián)系
均表示條件的判斷,switch語句表達式只能處理的是整型、字符型和枚舉類型,而選擇流程語句則沒有這樣的限制。但switch語句比選擇流程控制語句效率更高蚜迅。
isMemberOfClass 和 isKindOfClass 聯(lián)系與區(qū)別
- 聯(lián)系:兩者都能檢測一個對象是否是某個類的成員
- 區(qū)別:
isKindOfClass
不僅用來確定一個對象是否是一個類的成員,也可以用來確定一個對象是否派生自該類的類的成員 ,而isMemberOfClass
只能做到第一點舵匾。 - 舉例:如
ClassA
派 生 自NSObject
類 ,ClassA *a = [ClassA alloc] init]
;,[a isKindOfClass:[NSObject class]]
可以檢查出 a 是否是NSObject
派生類 的成員,但isMemberOfClass
做不到。
**iOS **開發(fā)中數(shù)據(jù)持久性有哪幾種?
數(shù)據(jù)存儲的核心都是寫文件谁不。
- 屬性列表:只有NSString坐梯、NSArray、NSDictionary刹帕、NSData可writeToFile吵血;存儲依舊是plist文件。plist文件可以存儲的7中數(shù)據(jù)類型:array偷溺、dictionary蹋辅、string、bool挫掏、data侦另、date、number尉共。
- 對象序列化(對象歸檔):對象序列化通過序列化的形式褒傅,鍵值關(guān)系存儲到本地,轉(zhuǎn)化成二進制流爸邢。通過runtime實現(xiàn)自動化歸檔/解檔,請參考這個文章拿愧。實現(xiàn)NSCoding協(xié)議必須實現(xiàn)的兩個方法:
1.編碼(對象序列化):把不能直接存儲到plist文件中得到數(shù)據(jù)杠河,轉(zhuǎn)化為二進制數(shù)據(jù),NSData浇辜,可以存儲到本地券敌;
2.解碼(對象反序列化):把二進制數(shù)據(jù)轉(zhuǎn)化為本來的類型。 - SQLite 數(shù)據(jù)庫:大量有規(guī)律的數(shù)據(jù)使用數(shù)據(jù)庫柳洋。
- CoreData :通過管理對象進行增待诅、刪、查熊镣、改操作的卑雁。它不是一個數(shù)據(jù)庫,不僅可以使用SQLite數(shù)據(jù)庫來保持數(shù)據(jù)绪囱,也可以使用其他的方式來存儲數(shù)據(jù)测蹲。如:XML。
CoreData的介紹:
- CoreData是面向?qū)ο蟮腁PI鬼吵,CoreData是iOS中非常重要的一項技術(shù)扣甲,幾乎在所有編寫的程序中,CoreData都作為數(shù)據(jù)存儲的基礎(chǔ)齿椅。
- CoreData是蘋果官方提供的一套框架琉挖,用來解決與對象聲明周期管理启泣、對象關(guān)系管理和持久化等方面相關(guān)的問題。
- 大多數(shù)情況下示辈,我們引用CoreData作為持久化數(shù)據(jù)的解決方案寥茫,并利用它作為持久化數(shù)據(jù)映射為內(nèi)存對象。提供的是對象-關(guān)系映射功能顽耳,也就是說坠敷,CoreData可以將Objective-C對象轉(zhuǎn)換成數(shù)據(jù),保存到SQL中射富,然后將保存后的數(shù)據(jù)還原成OC對象膝迎。
CoreData的特征:
- 通過CoreData管理應(yīng)用程序的數(shù)據(jù)模型,可以極大程度減少需要編寫的代碼數(shù)量胰耗。
- 將對象數(shù)據(jù)存儲在SQLite數(shù)據(jù)庫已獲得性能優(yōu)化限次。
- 提供NSFetchResultsController類用于管理表視圖的數(shù)據(jù),即將Core Data的持久化存儲在表視圖中柴灯,并對這些數(shù)據(jù)進行管理:增刪查改卖漫。
- 管理undo/redo操縱;
- 檢查托管對象的屬性值是否正確赠群。
Core Data的6成員對象
- 1.NSManageObject:被管理的數(shù)據(jù)記錄Managed Object Model是描述應(yīng)用程序的數(shù)據(jù)模型羊始,這個模型包含實體(Entity)、特性(Property)查描、讀取請求(Fetch Request)等突委。
- 2.NSManageObjectContext:管理對象上下文,持久性存儲模型對象冬三,參與數(shù)據(jù)對象進行各種操作的全過程匀油,并監(jiān)測數(shù)據(jù)對象的變化,以提供對undo/redo的支持及更新綁定到數(shù)據(jù)的UI勾笆。
- 3.NSPersistentStoreCoordinator:連接數(shù)據(jù)庫的Persistent Store Coordinator相當于數(shù)據(jù)文件管理器敌蚜,處理底層的對數(shù)據(jù)文件的讀取和寫入,一般我們與這個沒有交集窝爪。
- 4.NSManagedObjectModel:被管理的數(shù)據(jù)模型弛车、數(shù)據(jù)結(jié)構(gòu)。
- 5.NSFetchRequest:數(shù)據(jù)請求蒲每;
- 6.NSEntityDescription:表格實體結(jié)構(gòu)帅韧,還需知道.xcdatamodel文件編譯后為.momd或者.mom文件。
Core Data的功能
- 對于KVC和KVO完整且自動化的支持啃勉,除了為屬性整合KVO和KVC訪問方法外忽舟,還整合了適當?shù)募显L問方法來處理多值關(guān)系;
- 自動驗證屬性(property)值;
- 支持跟蹤修改和撤銷操作叮阅;
- 關(guān)系維護刁品,Core Data管理數(shù)據(jù)的關(guān)系傳播,包括維護對象間的一致性浩姥;
- 在內(nèi)存上和界面上分組挑随、過濾、組織數(shù)據(jù)勒叠;
- 自動支持對象存儲在外部數(shù)據(jù)倉庫的功能兜挨;
- 創(chuàng)建復(fù)雜請求:無需動手寫SQL語句,在獲取請求(fetch request)中關(guān)聯(lián)NSPredicate眯分。NSPreadicate支持基本功能拌汇、相關(guān)子查詢和其他高級的SQL特性。它支持正確的Unicode編碼弊决、區(qū)域感知查詢噪舀、排序和正則表達式;
- 延遲操作:Core Data使用懶加載(lazy loading)方式減少內(nèi)存負載飘诗,還支持部分實體化延遲加載和復(fù)制對象的數(shù)據(jù)共享機制与倡;
- 合并策略:Core Data內(nèi)置版本跟蹤和樂觀鎖(optimistic locking)來支持多用戶寫入沖突的解決,其中昆稿,樂觀鎖就是對數(shù)據(jù)沖突進行檢測纺座,若沖突就返回沖突的信息;
- 數(shù)據(jù)遷移:Core Data的Schema Migration工具可以簡化應(yīng)對數(shù)據(jù)庫結(jié)構(gòu)變化的任務(wù)溉潭,在某些情況允許你執(zhí)行高效率的數(shù)據(jù)庫原地遷移工作净响;
- 可選擇針對程序Controller層的集成,來支持UI的顯示同步Core Data在IPhone OS之上岛抄,提供NSFetchedResultsController對象來做相關(guān)工作别惦,在Mac OS X上我們用Cocoa提供的綁定(Binding)機制來完成的狈茉。
對象可以被copy的條件
- 只有實現(xiàn)了
NSCopying
和NSMutableCopying
協(xié)議的類的對象才能被拷貝,分為不可變拷貝和可變拷貝,具體區(qū)別戳這夫椭; -
NSCopying
協(xié)議方法為:
- (id)copyWithZone:(NSZone *)zone {
MyObject *copy = [[[self class] allocWithZone: zone] init];
copy.username = [self.username copyWithZone:zone];
return copy;
}
自動釋放池工作原理
- 自動釋放池是
NSAutorelease
類的一個實例,當向一個對象發(fā)送autorelease
消息時,該對象會自動入池,待池銷毀時,將會向池中所有對象發(fā)送一條release
消息,釋放對象。 -
[pool release]氯庆、 [pool drain]
表示的是池本身不會銷毀,而是池子中的臨時對象都被發(fā)送release
,從而將對象銷毀蹭秋。
在某個方法中 self.name = _name,name = _name 它 們有區(qū)別嗎,為什么?
- 前者是存在內(nèi)存管理的setter方法賦值,它會對_name對象進行保留或者拷貝操作
- 后者是普通賦值
- 一般來說堤撵,在對象的方法里成員變量和方法都是可以訪問的仁讨,我們通常會重寫Setter方法來執(zhí)行某些額外的工作。比如說实昨,外部傳一個模型過來洞豁,那么我會直接重寫Setter方法,當模型傳過來時,也就是意味著數(shù)據(jù)發(fā)生了變化丈挟,那么視圖也需要更新顯示刁卜,則在賦值新模型的同時也去刷新UI。
解釋self = [super init]方法
- 容錯處理,當父類初始化失敗,會返回一個nil,表示初始化失敗曙咽。由于繼承的關(guān)系,子類是需要擁有父類的實例和行為,因此,我們必須先初始化父類,然后再初始化子類
定義屬性時,什么時候用 assign蛔趴、retain、**copy **以及它們的之間的區(qū)別
-
assign
:普通賦值,一般常用于基本數(shù)據(jù)類型,常見委托設(shè)計模式, 以此來防止循環(huán)引用例朱。(我們稱之為弱引用). -
retain
:保留計數(shù),獲得到了對象的所有權(quán),引用計數(shù)在原有基礎(chǔ)上加1. -
copy
:一般認為,是在內(nèi)存中重新開辟了一個新的內(nèi)存空間,用來 存儲新的對象,和原來的對象是兩個不同的地址,引用計數(shù)分別為1孝情。但是當copy
對象為不可變對象時,那么copy
的作用相當于retain
。因為,這樣可以節(jié)約內(nèi)存空間
堆和棧的區(qū)別
-
棧區(qū)(stack)
由編譯器自動分配釋放 ,存放方法(函數(shù))的參數(shù)值, 局部變量的值等洒嗤,棧是向低地址擴展的數(shù)據(jù)結(jié)構(gòu)箫荡,是一塊連續(xù)的內(nèi)存的區(qū)域。即棧頂?shù)牡刂泛蜅5淖畲笕萘渴窍到y(tǒng)預(yù)先規(guī)定好的烁竭。 -
堆區(qū)(heap)
一般由程序員分配釋放, 若程序員不釋放,程序結(jié)束時由OS回收菲茬,向高地址擴展的數(shù)據(jù)結(jié)構(gòu),是不連續(xù)的內(nèi)存區(qū)域派撕,從而堆獲得的空間比較靈活婉弹。 -
碎片問題
:對于堆來講,頻繁的new/delete
勢必會造成內(nèi)存空間的不連續(xù)终吼,從而造成大量的碎片镀赌,使程序效率降低。對于棧來講际跪,則不會存在這個問題商佛,因為棧是先進后出的隊列,他們是如此的一一對應(yīng)姆打,以至于永遠都不可能有一個內(nèi)存塊從棧中間彈出. -
分配方式
:堆都是動態(tài)分配的良姆,沒有靜態(tài)分配的堆。棧有2種分配方式:靜態(tài)分配和動態(tài)分配幔戏。靜態(tài)分配是編譯器完成的玛追,比如局部變量的分配。動態(tài)分配由alloca函數(shù)進行分配闲延,但是棧的動態(tài)分配和堆是不同的痊剖,他的動態(tài)分配是由編譯器進行釋放,無需我們手工實現(xiàn)垒玲。 -
分配效率
:棧是機器系統(tǒng)提供的數(shù)據(jù)結(jié)構(gòu)陆馁,計算機會在底層對棧提供支持:分配專門的寄存器存放棧的地址,壓棧出棧都有專門的指令執(zhí)行合愈,這就決定了棧的效率比較高叮贩。堆則是C/C++函數(shù)庫提供的击狮,它的機制是很復(fù)雜的。 -
全局區(qū)(靜態(tài)區(qū))(static)
,全局變量和靜態(tài)變量的存儲是放在一塊 的,初始化的全局變量和靜態(tài)變量在一塊區(qū)域, 未初始化的全局變量和未初始化的靜態(tài)變量在相鄰的另一塊區(qū)域益老。程序結(jié)束后有系統(tǒng)釋放帘不。 -
文字常量區(qū)
—常量字符串就是放在這里的。程序結(jié)束后由系統(tǒng)釋放杨箭。 -
程序代碼區(qū)
—存放函數(shù)體的二進制代碼
怎樣使用performSelector傳入3個以上參數(shù)寞焙,其中一個為結(jié)構(gòu)體
因為系統(tǒng)提供的
performSelector
的API中,并沒有提供三個參數(shù)互婿。因此捣郊,我們只能傳數(shù)組或者字典,但是數(shù)組或者字典只有存入對象類型慈参,而結(jié)構(gòu)體并不是對象類型,我們只能通過對象放入結(jié)構(gòu)作為屬性來傳過去了.
- (id)performSelector:(SEL)aSelector;
- (id)performSelector:(SEL)aSelector withObject:(id)object;
- (id)performSelector:(SEL)aSelector withObject:
(id)object1 withObject:(id)object2;-
具體實現(xiàn)如下:
typedef struct HYBStruct {
int a;
int b;
} *my_struct;@interface HYBObject : NSObject @property (nonatomic, assign) my_struct arg3; @property (nonatomic, copy) NSString *arg1; @property (nonatomic, copy) NSString *arg2; @end @implementation HYBObject // 在堆上分配的內(nèi)存呛牲,我們要手動釋放掉 - (void)dealloc { free(self.arg3); } @end
測試:
my_struct str = (my_struct)(malloc(sizeof(my_struct)));
str->a = 1;
str->b = 2;
HYBObject *obj = [[HYBObject alloc] init];
obj.arg1 = @"arg1";
obj.arg2 = @"arg2";
obj.arg3 = str;
[self performSelector:@selector(call:) withObject:obj];
// 在回調(diào)時得到正確的數(shù)據(jù)的
- (void)call:(HYBObject *)obj {
NSLog(@"%d %d", obj.arg3->a, obj.arg3->b);
}
UITableViewCell上有個UILabel,顯示NSTimer實現(xiàn)的秒表時間驮配,手指滾動cell過程中娘扩,label是否刷新,為什么壮锻?
這是否刷新取決于timer加入到Run Loop中的Mode是什么琐旁。Mode主要是用來指定事件在運行循環(huán)中的優(yōu)先級的,分為:
-
NSDefaultRunLoopMode(kCFRunLoopDefaultMode)
:默認猜绣,空閑狀態(tài) -
UITrackingRunLoopMode
:ScrollView滑動時會切換到該Mode -
UIInitializationRunLoopMode
:run loop啟動時灰殴,會切換到該mode -
NSRunLoopCommonModes(kCFRunLoopCommonModes)
:Mode集合
蘋果公開提供的Mode有兩個: NSDefaultRunLoopMode(kCFRunLoopDefaultMode)
NSRunLoopCommonModes(kCFRunLoopCommonModes)
- 在編程中:如果我們把一個
NSTimer
對象以NSDefaultRunLoopMode(kCFRunLoopDefaultMode)
添加到主運行循環(huán)中的時候, ScrollView滾動過程中會因為mode的切換,而導(dǎo)致NSTimer
將不再被調(diào)度掰邢。當我們滾動的時候牺陶,也希望不調(diào)度,那就應(yīng)該使用默認模式辣之。但是掰伸,如果希望在滾動時,定時器也要回調(diào)怀估,那就應(yīng)該使用common mode狮鸭。
對于單元格重用的理解
- 當屏幕上滑出屏幕時,系統(tǒng)會把這個單元格添加到重用隊列中奏夫,等待被重用怕篷,當有新單元從屏幕外滑入屏幕內(nèi)時历筝,從重用隊列中找看有沒有可以重用的單元格酗昼,若有,就直接用梳猪,沒有就重新創(chuàng)建一個麻削。
解決cell重用的問題
- UITableView通過重用單元格來達到節(jié)省內(nèi)存的目的蒸痹,通過為每個單元格指定一個重用標示(reuseidentifier),即指定了單元格的種類呛哟,以及當單元格滾出屏幕時叠荠,允許恢復(fù)單元格以便復(fù)用。對于不同種類的單元格使用不同的ID扫责,對于簡單的表格榛鼎,一個標示符就夠了。
- 如一個TableView中有10個單元格鳖孤,但屏幕最多顯示4個者娱,實際上iPhone只為其分配4個單元格的內(nèi)存,沒有分配10個苏揣,當滾動單元格時黄鳍,屏幕內(nèi)顯示的單元格重復(fù)使用這4個內(nèi)存。實際上分配的cell的個數(shù)為屏幕最大顯示數(shù)平匈,當有新的cell進入屏幕時框沟,會隨機調(diào)用已經(jīng)滾出屏幕的Cell所占的內(nèi)存,這就是Cell的重用增炭。
- 對于多變的自定義Cell忍燥,這種重用機制會導(dǎo)致內(nèi)容出錯,為解決這種出錯的方法隙姿,把原來的
UITableViewCell *cell = [tableview dequeueReusableCellWithIdentifier:defineString]
修改為:UITableViewCell *cell = [tableview cellForRowAtIndexPath:indexPath];
這樣就解決掉cell重用機制導(dǎo)致的問題灾前。
有a、b孟辑、c哎甲、d 4個異步請求,如何判斷a饲嗽、b炭玫、c、d都完成執(zhí)行貌虾?如果需要a吞加、b、c尽狠、d順序執(zhí)行衔憨,該如何實現(xiàn)?
- 對于這四個異步請求袄膏,要判斷都執(zhí)行完成最簡單的方式就是通過GCD的group來實現(xiàn):
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, ^{ /*任務(wù)a / });
dispatch_group_async(group, queue, ^{ /任務(wù)b / });
dispatch_group_async(group, queue, ^{ /任務(wù)c / });
dispatch_group_async(group, queue, ^{ /任務(wù)d */ });
dispatch_group_notify(group,dispatch_get_main_queue(), ^{
// 在a践图、b、c沉馆、d異步執(zhí)行完成后码党,會回調(diào)這里
}); - 當然德崭,我們還可以使用非常老套的方法來處理,通過四個變量來標識a揖盘、b眉厨、c、d四個任務(wù)是否完成兽狭,然后在runloop中讓其等待憾股,當完成時才退出runloop。但是這樣做會讓后面的代碼得不到執(zhí)行箕慧,直到Run loop執(zhí)行完畢荔燎。
- 解釋:要求順序執(zhí)行,那么可以將任務(wù)放到串行隊列中销钝,自然就是按順序來異步執(zhí)行了有咨。
使用block有什么好處?使用NSTimer寫出一個使用block顯示(在UILabel上)秒表的代碼
- 代碼緊湊蒸健,傳值座享、回調(diào)都很方便,省去了寫代理的很多代碼似忧。
- NSTimer封裝成的block渣叛,具體實現(xiàn)
- 實現(xiàn)方法:
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0
repeats:YES
callback:^() {
weakSelf.secondsLabel.text = ...
}
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
一個view已經(jīng)初始化完畢,view上面添加了n個button盯捌,除用view的tag之外镜悉,還可以采用什么辦法來找到自己想要的button來修改button的值
有2種方法解決:
- 第一種:如果是點擊某個按鈕后闸昨,才會刷新它的值夸楣,其它不用修改磁餐,那么不用引用任何按鈕,直接在回調(diào)時幼衰,就已經(jīng)將接收響應(yīng)的按鈕給傳過來了靴跛,直接通過它修改即可。
- 第二種:點擊某個按鈕后渡嚣,所有與之同類型的按鈕都要修改值梢睛,那么可以通過在創(chuàng)建按鈕時將按鈕存入到數(shù)組中,在需要的時候遍歷查找识椰。
線程與進程的區(qū)別和聯(lián)系?
- 一個程序至少要有進城,一個進程至少要有一個線程.
- 進程:資源分配的最小獨立單元,進程是具有一定獨立功能的程序關(guān)于某個數(shù)據(jù)集合上的一次運行活動,進程是系統(tǒng)進行資源分配和調(diào)度的一個獨立單位.
- 線程:進程下的一個分支,是進程的實體,是CPU調(diào)度和分派的基本單元,它是比進程更小的能獨立運行的基本單位,線程自己基本不擁有系統(tǒng)資源,只擁有一點在運行中必不可少的資源(程序計數(shù)器绝葡、一組寄存器、棧)腹鹉,但是它可與同屬一個進程的其他線程共享進程所擁有的全部資源藏畅。
- 進程和線程都是由操作系統(tǒng)所體會的程序運行的基本單元,系統(tǒng)利用該基本單元實現(xiàn)系統(tǒng)對應(yīng)用的并發(fā)性种蘸。
- 進程和線程的主要差別在于它們是不同的操作系統(tǒng)資源管理方式墓赴。進程有獨立的地址空間,一個進程崩潰后航瞭,在保護模式下不會對其它進程產(chǎn)生影響诫硕,而線程只是一個進程中的不同執(zhí)行路徑。線程有自己的堆棧和局部變量刊侯,但線程之間沒有單獨的地址空間章办,一個線程死掉就等于整個進程死掉,所以多進程的程序要比多線程的程序健壯滨彻,但在進程切換時藕届,耗費資源較大,效率要差一些亭饵。
- 但對于一些要求同時進行并且又要共享某些變量的并發(fā)操作休偶,只能用線程,不能用進程辜羊。
多線程編程
-
NSThread
:當需要進行一些耗時操作時會把耗時的操作放到線程中踏兜。線程同步:多個線程同時訪問一個數(shù)據(jù)會出問題,NSlock八秃、線程同步塊碱妆、@synchronized(self){}。 -
NSOperationQueue操作隊列
(不需考慮線程同步問題)昔驱。編程的重點都放在main里面疹尾,NSInvocationOperation
、BSBlockOperation
骤肛、自定義Operation纳本。創(chuàng)建一個操作綁定相應(yīng)的方法,當把操作添加到操作隊列中時腋颠,操作綁定的方法就會自動執(zhí)行了饮醇,當把操作添加到操作隊列中時,默認會調(diào)用main方法秕豫。 - GCD(``Grand Central Dispatch`)宏大的中央調(diào)度朴艰,串行隊列、并發(fā)隊列混移、主線程隊列祠墅;
- 同步和異步:同步指第一個任務(wù)不執(zhí)行完,不會開始第二個歌径,異步是不管第一個有沒有執(zhí)行完毁嗦,都開始第二個。
- 串行和并行:串行是多個任務(wù)按一定順序執(zhí)行回铛,并行是多個任務(wù)同時執(zhí)行狗准;
- 代碼是在分線程執(zhí)行克锣,在主線程嘟列中刷新UI。
** 多線程編程是防止主線程堵塞腔长、增加運行效率的最佳方法袭祟。**
- Apple提供了NSOperation這個類,提供了一個優(yōu)秀的多線程編程方法捞附;
- 一個NSOperationQueue操作隊列巾乳,相當于一個線程管理器,而非一個線程鸟召,因為你可以設(shè)置這個線程管理器內(nèi)可以并行運行的線程數(shù)量等胆绊。
- 多線程是一個比較輕量級的方法來實現(xiàn)單個應(yīng)用程序內(nèi)多個代碼執(zhí)行路徑。
- iPhoneOS下的主線程的堆棧大小是1M欧募。第二個線程開始就是512KB压状,并且該值不能通過編譯器開關(guān)或線程API函數(shù)來更改,只有主線程有直接修改UI的能力跟继。
定時器與線程的區(qū)別;
- 定時器;可以執(zhí)行多次何缓,默認在主線程中。
- 線程:只能執(zhí)行一次还栓。
Apple設(shè)備尺寸和編程尺寸
TCP和UDP的區(qū)別于聯(lián)系
- TCP為傳輸控制層協(xié)議碌廓,為面向連接、可靠的剩盒、點到點的通信;
- UDP為用戶數(shù)據(jù)報協(xié)議辽聊,非連接的不可靠的點到多點的通信纪挎;
- TCP側(cè)重可靠傳輸讽营,UDP側(cè)重快速傳輸。
TCP連接的三次握手
- 第一次握手:客戶端發(fā)送syn包(syn=j)到服務(wù)器,并進入SYN_SEND狀態(tài)枫绅,等待服務(wù)器確認;
- 第二次握手:服務(wù)器收到syn包,必須確認客戶的SYN(ack=j+1)澎剥,同時自己也發(fā)送一個SYN包倡蝙,即SYN+ACK包,此時服務(wù)器進入SYN+RECV狀態(tài)褐荷;
- 第三次握手:客戶端收到服務(wù)器的SYN+ACK包,向服務(wù)器發(fā)送確認包ACK(ack=k+1)晕拆,此發(fā)送完畢末贾,客戶端和服務(wù)器進入ESTABLISHED狀態(tài)闸溃,完成三次狀態(tài)。
Scoket連接和HTTP連接的區(qū)別:
- HTTP協(xié)議是基于TCP連接的拱撵,是應(yīng)用層協(xié)議辉川,主要解決如何包裝數(shù)據(jù)。Socket是對TCP/IP協(xié)議的封裝拴测,Socket本身并不是協(xié)議乓旗,而是一個調(diào)用接口(API),通過Socket昼扛,我們才能使用TCP/IP協(xié)議寸齐。
- HTTP連接:短連接欲诺,客戶端向服務(wù)器發(fā)送一次請求抄谐,服務(wù)器響應(yīng)后連接斷開,節(jié)省資源扰法。服務(wù)器不能主動給客戶端響應(yīng)(除非采用HTTP長連接技術(shù))蛹含,iPhone主要使用類NSURLConnection。
- Socket連接:長連接塞颁,客戶端跟服務(wù)器端直接使用Socket進行連接浦箱,沒有規(guī)定連接后斷開,因此客戶端和服務(wù)器段保持連接通道祠锣,雙方可以主動發(fā)送數(shù)據(jù)酷窥,一般多用于游戲.Socket默認連接超時時間是30秒,默認大小是8K(理解為一個數(shù)據(jù)包大邪橥)蓬推。
HTTP協(xié)議的特點,關(guān)于HTTP請求GET和POST的區(qū)別
GET和POST的區(qū)別
:
HTTP超文本傳輸協(xié)議澡腾,是短連接沸伏,是客戶端主動發(fā)送請求,服務(wù)器做出響應(yīng)动分,服務(wù)器響應(yīng)之后毅糟,鏈接斷開。HTTP是一個屬于應(yīng)用層面向?qū)ο蟮膮f(xié)議澜公,HTTP有兩類報文:請求報文和響應(yīng)報文姆另。
HTTP請求報文:一個HTTP請求報文由請求行、請求頭部、空行和請求數(shù)據(jù)4部分組成迹辐。
HTTP響應(yīng)報文:由三部分組成:狀態(tài)行苟蹈、消息報頭、響應(yīng)正文右核。
-
GET請求:參數(shù)在地址后拼接慧脱,沒有請求數(shù)據(jù),不安全(因為所有參數(shù)都拼接在地址后面)贺喝,不適合傳輸大量數(shù)據(jù)(長度有限制菱鸥,為1024個字節(jié))。
GET提交躏鱼、請求的數(shù)據(jù)會附在URL之后氮采,即把數(shù)據(jù)放置在HTTP協(xié)議頭<requestline>中。 以染苛?分割URL和傳輸數(shù)據(jù)鹊漠,多個參數(shù)用&連接。如果數(shù)據(jù)是英文字母或數(shù)字茶行,原樣發(fā)送躯概, 如果是空格,轉(zhuǎn)換為+畔师,如果是中文/其他字符娶靡,則直接把字符串用BASE64加密。
POST請求:參數(shù)在請求數(shù)據(jù)區(qū)放著看锉,相對GET請求更安全姿锭,并且數(shù)據(jù)大小沒有限制。把提交的數(shù)據(jù)放置在HTTP包的包體
<request-body>
中.GET提交的數(shù)據(jù)會在地址欄顯示出來伯铣,而POST提交呻此,地址欄不會改變。
傳輸數(shù)據(jù)的大星还选:
- GET提交時焚鲜,傳輸數(shù)據(jù)就會受到URL長度限制,POST由于不是通過URL傳值蹬蚁,理論上書不受限恃泪。
安全性:
- POST的安全性要比GET的安全性高;
- 通過GET提交數(shù)據(jù)犀斋,用戶名和密碼將明文出現(xiàn)在URL上贝乎,比如登陸界面有可能被瀏覽器緩存。
- HTTPS:安全超文本傳輸協(xié)議(
Secure Hypertext Transfer Protocol
)叽粹,它是一個安全通信通道览效,基于HTTP開發(fā)却舀,用于客戶計算機和服務(wù)器之間交換信息,使用安全套結(jié)字層(SSI
)進行信息交換锤灿,即HTTP的安全版挽拔。
ASIHttpRequest、AFNetWorking之間的區(qū)別
- ASIHttpRequest功能強大但校,主要是在MRC下實現(xiàn)的螃诅,是對系統(tǒng)CFNetwork API進行了封裝,支持HTTP協(xié)議的CFHTTP状囱,配置比較復(fù)雜术裸,并且ASIHttpRequest框架默認不會幫你監(jiān)聽網(wǎng)絡(luò)改變,如果需要讓ASIHttpRequest幫你監(jiān)聽網(wǎng)絡(luò)狀態(tài)改變亭枷,并且手動開始這個功能袭艺。
- AFNetWorking構(gòu)建于NSURLConnection、NSOperation以及其他熟悉的Foundation技術(shù)之上叨粘。擁有良好的架構(gòu)猾编,豐富的API及模塊構(gòu)建方式,使用起來非常輕松升敲。它基于NSOperation封裝的答倡,AFURLConnectionOperation子類。
- ASIHttpRequest是直接操作對象ASIHttpRequest是一個實現(xiàn)了NSCoding協(xié)議的NSOperation子類冻晤;AFNetWorking直接操作對象的AFHttpClient苇羡,是一個實現(xiàn)NSCoding和NSCopying協(xié)議的NSObject子類绸吸。
- 同步請求:ASIHttpRequest直接通過調(diào)用一個
startSynchronous
方法鼻弧;AFNetWorking默認沒有封裝同步請求,如果開發(fā)者需要使用同步請求锦茁,則需要重寫getPath:paraments:success:failures
方法攘轩,對于AFHttpRequestOperation進行同步處理。 - 性能對比:AFNetworking請求優(yōu)于ASIHttpRequest码俩;
XML數(shù)據(jù)解析方式各有什么不同度帮,JSON解析有哪些框架?
- XML數(shù)據(jù)解析的兩種解析方式:DOM解析和SAX解析稿存;
- DOM解析必須完成DOM樹的構(gòu)造笨篷,在處理規(guī)模較大的XML文檔時就很耗內(nèi)存,占用資源較多瓣履,讀入整個XML文檔并構(gòu)建一個駐留內(nèi)存的樹結(jié)構(gòu)(節(jié)點樹)率翅,通過遍歷樹結(jié)構(gòu)可以檢索任意XML節(jié)點,讀取它的屬性和值袖迎,通常情況下冕臭,可以借助XPath查詢XML節(jié)點腺晾;
- SAX與DOM不同,它是事件驅(qū)動模型辜贵,解析XML文檔時每遇到一個開始或者結(jié)束標簽悯蝉、屬性或者一條指令時,程序就產(chǎn)生一個事件進行相應(yīng)的處理托慨,一邊讀取XML文檔一邊處理鼻由,不必等整個文檔加載完才采取措施,當在讀取解析過程中遇到需要處理的對象厚棵,會發(fā)出通知進行處理嗡靡。因此,SAX相對于DOM來說更適合操作大的XML文檔窟感。
-JSON解析:性能比較好的主要是第三方的JSONKIT和iOS自帶的JSON解析類讨彼,其中自帶的JSON解析性能最高,但只能用于iOS5之后柿祈。
如何進行真機調(diào)試
- 1.首先需要用
鑰匙串
創(chuàng)建一個鑰匙(key)哈误; - 2.將鑰匙串上傳到官網(wǎng),獲取iOS Development證書躏嚎;
- 3.創(chuàng)建App ID即我們應(yīng)用程序中的Boundle ID蜜自;
- 4.添加Device ID即UDID;
- 5.通過勾選前面所創(chuàng)建的證書:App ID卢佣、Device ID重荠;
- 6.生成mobileprovision文件;
- 7.先決條件:申請開發(fā)者賬號 99美刀
APP發(fā)布的上架流程
- 1.登錄應(yīng)用發(fā)布網(wǎng)站添加應(yīng)用信息虚茶;
- 2.下載安裝發(fā)布證書戈鲁;
- 3.選擇發(fā)布證書,使用Archive編譯發(fā)布包嘹叫,用Xcode將代碼(發(fā)布包)上傳到服務(wù)器婆殿;
- 4.等待審核通過;
- 5.生成IPA:菜單欄->Product->Archive.
SVN的使用
- SVN=版本控制+備份服務(wù)器,可以把SVN當成備份服務(wù)器罩扇,并且可以幫助你記住每次上服務(wù)器的檔案內(nèi)容婆芦,并自動賦予每次變更的版本;
- SVN的版本控制:所有上傳版本都會幫您記錄下來喂饥,也有版本分支及合并等功能消约。SVN可以讓不同的開發(fā)者存取同樣的檔案,并且利用SVN Server作為檔案同步的機制员帮,即您有檔案更新時或粮,無需將檔案寄送給您的開發(fā)成員。SVN的存放檔案方式是采用差異備份的方式集侯,即會備份到不同的地方被啼,節(jié)省硬盤空間帜消,也可以對非文字文件進行差異備份。
- SVN的重要性:備份工作檔案的重要性浓体、版本控管的重要性泡挺、伙伴間的數(shù)據(jù)同步的重要性、備份不同版本是很耗費硬盤空間的命浴;
- 防止沖突:
1.防止代碼沖突:不要多人同時修改同一文件娄猫,例如:A、B都修改同一個文件生闲,先讓A修改媳溺,然后提交到服務(wù)器,然后B更新下來碍讯,再進行修改悬蔽;
2.服務(wù)器上的項目文件Xcodeproj,僅讓一個人管理提交捉兴,其他人只更新蝎困,防止文件發(fā)生沖突。
如何進行網(wǎng)絡(luò)消息推送
- 一種是Apple自己提供的通知服務(wù)(APNS服務(wù)器)倍啥、一種是用第三方推送機制禾乘。
- 首先應(yīng)用發(fā)送通知,系統(tǒng)彈出提示框詢問用戶是否允許虽缕,當用戶允許后向蘋果服務(wù)器(APNS)請求deviceToken始藕,并由蘋果服務(wù)器發(fā)送給自己的應(yīng)用,自己的應(yīng)用將DeviceToken發(fā)送自己的服務(wù)器氮趋,自己服務(wù)器想要發(fā)送網(wǎng)絡(luò)推送時將deviceToken以及想要推送的信息發(fā)送給蘋果服務(wù)器伍派,蘋果服務(wù)器將信息發(fā)送給應(yīng)用。
- 推送信息內(nèi)容凭峡,總?cè)萘坎怀^256個字節(jié)拙已;
- iOS SDK本身提供的APNS服務(wù)器推送,它可以直接推送給目標用戶并根據(jù)您的方式彈出提示摧冀。
優(yōu)點:不論應(yīng)用是否開啟,都會發(fā)送到手機端系宫;
缺點:消息推送機制是蘋果服務(wù)端控制索昂,個別時候可能會有延遲,因為蘋果服務(wù)器也有隊列來處理所有的消息請求扩借; - 第三方推送機制椒惨,普遍使用Socket機制來實現(xiàn),幾乎可以達到即時的發(fā)送到目標用戶手機端潮罪,適用于即時通訊類應(yīng)用康谆。
優(yōu)點:實時的领斥,取決于心跳包的節(jié)奏;
缺點:iOS系統(tǒng)的限制沃暗,應(yīng)用不能長時間的后臺運行月洛,所以應(yīng)用關(guān)閉的情況下這種推送機制不可用。
網(wǎng)絡(luò)七層協(xié)議
-
應(yīng)用層:
1.用戶接口孽锥、應(yīng)用程序嚼黔;
2.Application典型設(shè)備:網(wǎng)關(guān);
3.典型協(xié)議惜辑、標準和應(yīng)用:TELNET唬涧、FTP、HTTP -
表示層:
1.數(shù)據(jù)表示盛撑、壓縮和加密presentation
2.典型設(shè)備:網(wǎng)關(guān)
3.典型協(xié)議碎节、標準和應(yīng)用:ASCLL、PICT抵卫、TIFF钓株、JPEG|MPEG
4.表示層相當于一個東西的表示,表示的一些協(xié)議陌僵,比如圖片轴合、聲音和視頻MPEG。 -
會話層:
1.會話的建立和結(jié)束碗短;
2.典型設(shè)備:網(wǎng)關(guān)受葛;
3.典型協(xié)議、標準和應(yīng)用:RPC偎谁、SQL总滩、NFS、X WINDOWS巡雨、ASP -
傳輸層:
1.主要功能:端到端控制Transport闰渔;
2.典型設(shè)備:網(wǎng)關(guān);
3.典型協(xié)議铐望、標準和應(yīng)用:TCP冈涧、UDP、SPX -
網(wǎng)絡(luò)層:
1.主要功能:路由正蛙、尋址Network督弓;
2.典型設(shè)備:路由器;
3.典型協(xié)議乒验、標準和應(yīng)用:IP愚隧、IPX、APPLETALK锻全、ICMP狂塘; -
數(shù)據(jù)鏈路層:
1.主要功能:保證無差錯的疏忽鏈路的data link录煤;
2.典型設(shè)備:交換機、網(wǎng)橋荞胡、網(wǎng)卡妈踊;
3.典型協(xié)議、標準和應(yīng)用:802.2硝训、802.3ATM响委、HDLC、FRAME RELAY窖梁; -
物理層:
1.主要功能:傳輸比特流Physical赘风;
2.典型設(shè)備:集線器、中繼器
3.典型協(xié)議纵刘、標準和應(yīng)用:V.35邀窃、EIA/TIA-232.
對NSUserDefaults的理解
- NSUserDefaults:系統(tǒng)提供的一種存儲數(shù)據(jù)的方式,主要用于保存少量的數(shù)據(jù)假哎,默認存儲到library下的Preferences文件夾瞬捕。
SDWebImage原理
調(diào)用類別的方法:
- 從內(nèi)存中(字典)找圖片(當這個圖片在本次程序加載過),找到直接使用舵抹;
- 從沙盒中找肪虎,找到直接使用,緩存到內(nèi)存惧蛹。
- 從網(wǎng)絡(luò)上獲取扇救,使用,緩存到內(nèi)存香嗓,緩存到沙盒迅腔。
OC中是否有二維數(shù)組,如何實現(xiàn)二維數(shù)組
- OC中沒有二維數(shù)組靠娱,可通過嵌套數(shù)組實現(xiàn)二維數(shù)組沧烈。
LayoutSubViews在什么時候被調(diào)用?
- 當View本身的frame改變時像云,會調(diào)用這個方法锌雀。
深拷貝和淺拷貝
- 如果對象有個指針型成員變量指向內(nèi)存中的某個資源,那么如何復(fù)制這個對象呢苫费?你會只是復(fù)制指針的值傳給副本的新對象嗎汤锨?指針只是存儲內(nèi)存中資源地址的占位符。在復(fù)制操作中百框,如果只是將指針復(fù)制給新對象,那么底層的資源實際上仍然由兩個實例在共享牍汹。
- 淺復(fù)制:兩個實例的指針仍指向內(nèi)存中的同一資源铐维,只復(fù)制指針值而不是實際資源柬泽;
- 深復(fù)制:不僅復(fù)制指針值,還復(fù)制指向指針所指向的資源嫁蛇。如下圖:
單例模式理解與使用
- 單例模式是一種常用設(shè)計模式锨并,單例模式是一個類在系統(tǒng)中只有一個實例對象。通過全局的一個入口點對這個實例對象進行訪問睬棚;
- iOS中單例模式的實現(xiàn)方式一般分為兩種:非ARC和ARC+GCD第煮。
對沙盒的理解
- 每個iOS應(yīng)用都被限制在“沙盒”中,沙盒相當于一個加了僅主人可見權(quán)限的文件夾抑党,及時在應(yīng)用程序安裝過程中包警,系統(tǒng)為每個單獨的應(yīng)用程序生成它的主目錄和一些關(guān)鍵的子目錄。蘋果對沙盒有幾條限制:
1. 應(yīng)用程序在自己的沙盒中運作底靠,但是不能訪問任何其他應(yīng)用程序的沙盒害晦;
2. 應(yīng)用之間不能共享數(shù)據(jù)怒允,沙盒里的文件不能被復(fù)制到其他
應(yīng)用程序的文件夾中雳灾,也不能把其他應(yīng)用文件夾復(fù)制到沙盒中低散;
3. 蘋果禁止任何讀寫沙盒以外的文件梆惯,禁止應(yīng)用程序?qū)?nèi)容寫到沙盒以外的文件夾中万哪;
4. 沙盒目錄里有三個文件夾:Documents——存儲
應(yīng)用程序的數(shù)據(jù)文件帘撰,存儲用戶數(shù)據(jù)或其他定期備份的信息政钟;
Library下有兩個文件夾蜈敢,Caches存儲應(yīng)用程序再次啟動所需的信息雕凹,
Preferences包含應(yīng)用程序的偏好設(shè)置文件殴俱,不可在這更改偏好設(shè)置;
temp存放臨時文件即應(yīng)用程序再次啟動不需要的文件请琳。 - 獲取沙盒根目錄的方法粱挡,有幾種方法:用NSHomeDirectory獲取。
- 獲取Document路徑:
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES)
.
對瀑布流的理解
- 首先圖片的寬度都是一樣的俄精,1.將圖片等比例壓縮询筏,讓圖片不變形;2.計算圖片最低應(yīng)該擺放的位置竖慧,哪一列低就放在哪嫌套;3.進行最優(yōu)排列,在ScrollView的基礎(chǔ)上添加兩個tableView圾旨,然后將之前所計算的scrollView的高度通過tableView展示出來踱讨。
- 如何使用兩個TableView產(chǎn)生聯(lián)動:將兩個tableView的滾動事件禁止掉,最外層scrollView滾動時將兩個TableView跟著滾動砍的,并且更改contentOffset痹筛,這樣產(chǎn)生效果滾動的兩個tableView。
ViewController 的 loadView,、viewDidLoad,帚稠、viewDidUnload 分別是在什么時候調(diào)用的谣旁?
-
viewDidLoad
在view從nib文件初始化時調(diào)用,loadView
在controller的view為nil時調(diào)用滋早。 - 此方法在編程實現(xiàn)view時調(diào)用,view控制器默認會注冊
memory warning notification
,當view controller
的任何view沒有用的時候榄审,viewDidUnload
會被調(diào)用,在這里實現(xiàn)將retain
的view release
,如果是retain
的IBOutlet view
屬性則不要在這里release
,IBOutlet
會負責(zé)release
杆麸。
關(guān)鍵字volatile有什么含意?并給出三個不同的例子:
- 一個定義為
volatile
的變量是說這變量可能會被意想不到地改變搁进,這樣,編譯器就不會去假設(shè)這個變量的值了昔头。精確地說就是饼问,優(yōu)化器在用到這個變量時必須每次都小心地重新讀取這個變量的值,而不是使用保存在寄存器里的備份减细。下面是volatile
變量的幾個例子:
? 并行設(shè)備的硬件寄存器(如:狀態(tài)寄存器)匆瓜;
?一個中斷服務(wù)子程序中會訪問到的非自動變量(Non-automatic variables);
? 多線程應(yīng)用中被幾個任務(wù)共享的變量未蝌。
@synthesize驮吱、@dynamic的理解
-
@synthesize
是系統(tǒng)自動生成getter和setter屬性聲明;@synthesize
的意思是,除非開發(fā)人員已經(jīng)做了萧吠,否則由編譯器生成相應(yīng)的代碼左冬,以滿足屬性聲明; -
@dynamic
是開發(fā)者自已提供相應(yīng)的屬性聲明,@dynamic
意思是由開發(fā)人員提供相應(yīng)的代碼:對于只讀屬性需要提供getter
纸型,對于讀寫屬性需要提供setter
和getter
拇砰。查閱了一些資料確定@dynamic
的意思是告訴編譯器,屬性的獲取與賦值方法由用戶自己實現(xiàn), 不自動生成。
frame和bounds有什么不同狰腌?
- frame指的是:該view在父view坐標系統(tǒng)中的位置和大小除破。(參照點是父親的坐標系統(tǒng))
- bounds指的是:該view在本身坐標系統(tǒng)中的位置和大小。(參照點是本身坐標系統(tǒng))
view的touch事件有哪些琼腔?
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
自定義實現(xiàn)UITabbarController的原理
- 運用字典瑰枫,點擊五個按鈕的一個可以從字典里選擇一個控制器對象,將其View顯示到主控制器視圖上丹莲。
iOS中的響應(yīng)者鏈的工作原理
- 每一個應(yīng)用有一個響應(yīng)者鏈光坝,我們的視圖結(jié)構(gòu)是一個N叉樹(一個視圖可以有多個子視圖,一個子視圖同一時刻只有一個父視圖),而每一個繼承
UIResponder
的對象都可以在這個N叉樹中扮演一個節(jié)點甥材。 - 當葉節(jié)點成為最高響應(yīng)者的時候盯另,從這個葉節(jié)點開始往其父節(jié)點開始追朔出一條鏈,那么對于這一個葉節(jié)點來講洲赵,這一條鏈就是當前的響應(yīng)者鏈鸳惯。響應(yīng)者鏈將系統(tǒng)捕獲到的UIEvent與UITouch從葉節(jié)點開始層層向下分發(fā)商蕴,期間可以選擇停止分發(fā),也可以選擇繼續(xù)向下分發(fā)悲敷。
- 如需了解更多細節(jié)究恤,請讀這篇文章俭令。
View和View之間傳值方式
- 對象的property屬性傳值后德;
- 方法參數(shù)傳值;
- NSUserDefault傳值抄腔;
- 塊傳值瓢湃。
property屬性的修飾符的作用
- getter=getName、setter=setName:設(shè)置setter與getter的方法名赫蛇;
- readwrite绵患、readonly:設(shè)置可供訪問級別;
- assign:方法直接賦值悟耘,不進行任何retain操作落蝙,為了解決原類型與環(huán)循引用問題;
- retain:其setter方法對參數(shù)進行release舊值再retain新值暂幼,所有實現(xiàn)都是這個順序筏勒;
- copy:其setter方法進行copy操作,與retain處理流程一樣旺嬉,先對舊值release管行,再copy出新的對象,retainCount為1邪媳。這是為了減少對上下文的依賴而引入的機制捐顷。
- nonatomic:非原子性訪問,不加同步雨效, 多線程并發(fā)訪問會提高性能迅涮。注意,如果不加此屬性徽龟,則默認是兩個訪問方法都為原子型事務(wù)訪問叮姑。
對于Run Loop的理解
- RunLoop,是多線程的法寶顿肺,即一個線程一次只能執(zhí)行一個任務(wù)戏溺,執(zhí)行完任務(wù)后就會退出線程。主線程執(zhí)行完即時任務(wù)時會繼續(xù)等待接收事件而不退出屠尊。非主線程通常來說就是為了執(zhí)行某一任務(wù)的旷祸,執(zhí)行完畢就需要歸還資源,因此默認是不運行RunLoop的讼昆;
- 每一個線程都有其對應(yīng)的RunLoop托享,只是默認只有主線程的RunLoop是啟動的,其它子線程的RunLoop默認是不啟動的,若要啟動則需要手動啟動闰围;
- 在一個單獨的線程中赃绊,如果需要在處理完某個任務(wù)后不退出,繼續(xù)等待接收事件羡榴,則需要啟用RunLoop碧查;
- NSRunLoop提供了一個添加NSTimer的方法,可以指定Mode校仑,如果要讓任何情況下都回調(diào)忠售,則需要設(shè)置Mode為Common模式;
- 實質(zhì)上迄沫,對于子線程的runloop默認是不存在的稻扬,因為蘋果采用了懶加載的方式。如果我們沒有手動調(diào)用
[NSRunLoop currentRunLoop]
的話羊瘩,就不會去查詢是否存在當前線程的RunLoop泰佳,也就不會去加載,更不會創(chuàng)建尘吗。
SQLite中常用的SQL語句
- 創(chuàng)建表:creat table 表名 (字段名 字段數(shù)據(jù)類型 是否為主鍵, 字段名 字段數(shù)據(jù)類型, 字段名 字段數(shù)據(jù)類型...)逝她;
- 增: insert into 表名 (字段1, 字段2...) values (值1, 值2...);
- 刪: delete from 表名 where 字段 = 值摇予;
XIB與Storyboards的優(yōu)缺點
優(yōu)點:
- XIB:在編譯前就提供了可視化界面汽绢,可以直接拖控件,也可以直接給控件添加約束侧戴,更直觀一些宁昭,而且類文件中就少了創(chuàng)建控件的代碼,確實簡化不少酗宋,通常每個XIB對應(yīng)一個類积仗。
- Storyboard:在編譯前提供了可視化界面,可拖控件蜕猫,可加約束寂曹,在開發(fā)時比較直觀,而且一個storyboard可以有很多的界面回右,每個界面對應(yīng)一個類文件隆圆,通過storybard,可以直觀地看出整個App的結(jié)構(gòu)翔烁。
缺點:
- XIB:需求變動時渺氧,需要修改XIB很大,有時候甚至需要重新添加約束蹬屹,導(dǎo)致開發(fā)周期變長侣背。XIB載入相比純代碼自然要慢一些白华。對于比較復(fù)雜邏輯控制不同狀態(tài)下顯示不同內(nèi)容時,使用XIB是比較困難的贩耐。當多人團隊或者多團隊開發(fā)時弧腥,如果XIB文件被發(fā)動,極易導(dǎo)致沖突潮太,而且解決沖突相對要困難很多管搪。
- Storyboard:需求變動時,需要修改storyboard上對應(yīng)的界面的約束消别,與XIB一樣可能要重新添加約束抛蚤,或者添加約束會造成大量的沖突,尤其是多團隊開發(fā)寻狂。對于復(fù)雜邏輯控制不同顯示內(nèi)容時,比較困難朋沮。當多人團隊或者多團隊開發(fā)時蛇券,大家會同時修改一個storyboard,導(dǎo)致大量沖突樊拓,解決起來相當困難纠亚。
將字符串“2015-04-10”格式化日期轉(zhuǎn)為NSDate類型
NSString *timeStr = @"2015-04-10";
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"yyyy-MM-dd";
formatter.timeZone = [NSTimeZone defaultTimeZone];
NSDate *date = [formatter dateFromString:timeStr];
// 2015-04-09 16:00:00 +0000
NSLog(@"%@", date);
隊列和多線程的使用原理
在iOS中隊列分為以下幾種:
- 串行隊列:隊列中的任務(wù)只會順序執(zhí)行;
dispatch_queue_t q = dispatch_queue_create("...", DISPATCH_QUEUE_SERIAL); - 并行隊列: 隊列中的任務(wù)通常會并發(fā)執(zhí)行筋夏;
dispatch_queue_t q = dispatch_queue_create("......",DISPATCH_QUEUE_CONCURRENT); - 全局隊列:是系統(tǒng)的蒂胞,直接拿過來(GET)用就可以;與并行隊列類似条篷;
dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); - 主隊列:每一個應(yīng)用程序?qū)?yīng)唯一主隊列骗随,直接GET即可;在多線程開發(fā)中赴叹,使用主隊列更新UI鸿染;
dispatch_queue_t q = dispatch_get_main_queue(); -
更多細節(jié)見下圖:
內(nèi)存的使用和優(yōu)化的注意事項
- 重用問題:如UITableViewCells、UICollectionViewCells乞巧、UITableViewHeaderFooterViews設(shè)置正確的reuseIdentifier涨椒,充分重用;
- 盡量把views設(shè)置為不透明:當opque為NO的時候绽媒,圖層的半透明取決于圖片和其本身合成的圖層為結(jié)果蚕冬,可提高性能;
- 不要使用太復(fù)雜的XIB/Storyboard:載入時就會將XIB/storyboard需要的所有資源是辕,包括圖片全部載入內(nèi)存囤热,即使未來很久才會使用。那些相比純代碼寫的延遲加載免糕,性能及內(nèi)存就差了很多赢乓;
-
選擇正確的數(shù)據(jù)結(jié)構(gòu):學(xué)會選擇對業(yè)務(wù)場景最合適的數(shù)組結(jié)構(gòu)是寫出高效代碼的基礎(chǔ)忧侧。比如,數(shù)組: 有序的一組值牌芋。使用索引來查詢很快蚓炬,使用值查詢很慢,插入/刪除很慢躺屁。字典: 存儲鍵值對肯夏,用鍵來查找比較快。集合: 無序的一組值犀暑,用值來查找很快驯击,插入/刪除很快。
gzip/zip壓縮:當從服務(wù)端下載相關(guān)附件時耐亏,可以通過gzip/zip壓縮后再下載徊都,使得內(nèi)存更小,下載速度也更快广辰。 - 延遲加載:對于不應(yīng)該使用的數(shù)據(jù)暇矫,使用延遲加載方式。對于不需要馬上顯示的視圖择吊,使用延遲加載方式李根。比如,網(wǎng)絡(luò)請求失敗時顯示的提示界面几睛,可能一直都不會使用到房轿,因此應(yīng)該使用延遲加載。
- 數(shù)據(jù)緩存:對于cell的行高要緩存起來所森,使得reload數(shù)據(jù)時囱持,效率也極高。而對于那些網(wǎng)絡(luò)數(shù)據(jù)必峰,不需要每次都請求的洪唐,應(yīng)該緩存起來,可以寫入數(shù)據(jù)庫吼蚁,也可以通過plist文件存儲凭需。
-
處理內(nèi)存警告:一般在基類統(tǒng)一處理內(nèi)存警告,將相關(guān)不用資源立即釋放掉
重用大開銷對象:一些objects的初始化很慢肝匆,比如NSDateFormatter
和NSCalendar
粒蜈,但又不可避免地需要使用它們。通常是作為屬性存儲起來旗国,防止反復(fù)創(chuàng)建枯怖。 - 避免反復(fù)處理數(shù)據(jù):許多應(yīng)用需要從服務(wù)器加載功能所需的常為JSON或者XML格式的數(shù)據(jù)。在服務(wù)器端和客戶端使用相同的數(shù)據(jù)結(jié)構(gòu)很重要;
- 使用Autorelease Pool:在某些循環(huán)創(chuàng)建臨時變量處理數(shù)據(jù)時能曾,自動釋放池以保證能及時釋放內(nèi)存;
- 正確選擇圖片加載方式:詳情閱讀細讀UIImage加載方式
UIViewController的完整生命周期
-[ViewController initWithNibName:bundle:]度硝;
-[ViewController init]肿轨;
-[ViewController loadView];
-[ViewController viewDidLoad]蕊程;
-[ViewController viewWillAppear:]椒袍;
-[ViewController viewWillLayoutSubviews:];
-[ViewController viewDidLayoutSubviews:]藻茂;
-[ViewController viewDidAppear:]驹暑;
-[ViewController viewWillDisappear:];
-[ViewController viewDidDisappear:]辨赐;
-[ViewController viewWillUnload:]优俘;
-[ViewController viewDidUnload:];
UIImageView添加圓角
最直接的方法就是使用如下屬性設(shè)置:
imgView.layer.cornerRadius = 10;
// 這一行代碼是很消耗性能的
imgView.clipsToBounds = YES;
**這是離屏渲染(off-screen-rendering)掀序,消耗性能的**
-
給UIImage添加生成圓角圖片的擴展API:這是on-screen-rendering
- (UIImage *)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; }
文章更新記錄
- 2017.03.10 更正UIViewController的生命周期帆焕;
- 2018.09.02 更正文字錯誤;