斐波那契數(shù)列(Fibonacci sequence)
func Fib() -> Int {
var prev = 0
var curr = 1
for _ in 1 ..< 100 {
var temp = curr
curr = prev + curr
prev = temp
}
return curr
}
nil、Nil、NULL、NSNull的區(qū)別
nil:指向一個對象的空指針,對objective c id 對象賦空值.
Nil:指向一個類的空指針,表示對類進行賦空值.
NULL:指向其他類型(如:基本類型、C類型)的空指針, 用于對非對象指針賦空值.
NSNull:在集合對象中,表示空值的對象.
網(wǎng)絡(luò)圖片處理

SDWebImage的使用
第一步,下載SDWebImage,導(dǎo)入工程。github托管地址https://github.com/rs/SDWebImage
第二步,在需要的地方導(dǎo)入頭文件
1 #import "UIImageView+WebCache.h"
第三步,調(diào)用sd_setImageWithURL:方法緩存圖片,注意,這就是新版本的新方法,舊方法是setImageWithURL:。下面將幾個方法都介紹一下。
1. sd_setImageWithURL:
/圖片緩存的基本代碼,就是這么簡單
[self.image1 sd_setImageWithURL:imagePath1];
2. sd_setImageWithURL: completed:
//用block 可以在圖片加載完成之后做些事情
[self.image2 sd_setImageWithURL:imagePath2 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
NSLog(@"這里可以在圖片加載完成之后做些事情");
}];
3. sd_setImageWithURL: placeholderImage:
//給一張默認(rèn)圖片,先使用默認(rèn)圖片,當(dāng)圖片加載完成后再替換
[self.image1 sd_setImageWithURL:imagePath1 placeholderImage:[UIImage imageNamed:@"default"]];
4. sd_setImageWithURL: placeholderImage: completed:
//使用默認(rèn)圖片,而且用block 在完成后做一些事情
[self.image1 sd_setImageWithURL:imagePath1 placeholderImage:[UIImage imageNamed:@"default"] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
NSLog(@"圖片加載完成后做的事情");
}];
5. sd_setImageWithURL: placeholderImage: options:
//options 選擇方式
[self.image1 sd_setImageWithURL:imagePath1 placeholderImage:[UIImage imageNamed:@"default"] options:SDWebImageRetryFailed];
其他就不一一介紹了,oc是自文檔語言,看方法名就知道干什么的了。除了帶options選項的方法,其他的方法都是綜合存儲,也就是內(nèi)存緩存和磁盤緩存結(jié)合的方式,如果你只需要內(nèi)存緩存,那么在options這里選擇SDWebImageCacheMemoryOnly就可以了。
如果不想深入了解,到這里你已經(jīng)可以用SDWebimage進行圖片緩存了,接下來我要解釋options的所有選項,以及SDWebImage內(nèi)部執(zhí)行流程。
一、options所有選項:
//失敗后重試
SDWebImageRetryFailed = 1 << 0,
//UI交互期間開始下載,導(dǎo)致延遲下載比如UIScrollView減速。
SDWebImageLowPriority = 1 << 1,
//只進行內(nèi)存緩存
SDWebImageCacheMemoryOnly = 1 << 2,
//這個標(biāo)志可以漸進式下載,顯示的圖像是逐步在下載
SDWebImageProgressiveDownload = 1 << 3,
//刷新緩存
SDWebImageRefreshCached = 1 << 4,
//后臺下載
SDWebImageContinueInBackground = 1 << 5,
//NSMutableURLRequest.HTTPShouldHandleCookies = YES;
SDWebImageHandleCookies = 1 << 6,
//允許使用無效的SSL證書
//SDWebImageAllowInvalidSSLCertificates = 1 << 7,
//優(yōu)先下載
SDWebImageHighPriority = 1 << 8,
//延遲占位符
SDWebImageDelayPlaceholder = 1 << 9,
//改變動畫形象
SDWebImageTransformAnimatedImage = 1 << 10,
SDWebImage內(nèi)部實現(xiàn)過程
1. 入口 setImageWithURL:placeholderImage:options: 會先把 placeholderImage 顯示,然后 SDWebImageManager 根據(jù) URL 開始處理圖片。
2. 進入 SDWebImageManager-downloadWithURL:delegate:options:userInfo:,交給 SDImageCache 從緩存查找圖片是否已經(jīng)下載 queryDiskCacheForKey:delegate:userInfo:.
3. 先從內(nèi)存圖片緩存查找是否有圖片,如果內(nèi)存中已經(jīng)有圖片緩存,SDImageCacheDelegate 回調(diào) imageCache:didFindImage:forKey:userInfo: 到 SDWebImageManager。
4. SDWebImageManagerDelegate 回調(diào) webImageManager:didFinishWithImage: 到 UIImageView+WebCache 等前端展示圖片。
5. 如果內(nèi)存緩存中沒有,生成 NSInvocationOperation 添加到隊列開始從硬盤查找圖片是否已經(jīng)緩存。
6. 根據(jù) URLKey 在硬盤緩存目錄下嘗試讀取圖片文件。這一步是在 NSOperation 進行的操作,所以回主線程進行結(jié)果回調(diào) notifyDelegate:。
7. 如果上一操作從硬盤讀取到了圖片,將圖片添加到內(nèi)存緩存中(如果空閑內(nèi)存過小,會先清空內(nèi)存緩存)。SDImageCacheDelegate 回調(diào) imageCache:didFindImage:forKey:userInfo:。進而回調(diào)展示圖片。
8. 如果從硬盤緩存目錄讀取不到圖片,說明所有緩存都不存在該圖片,需要下載圖片,回調(diào) imageCache:didNotFindImageForKey:userInfo:。
9. 共享或重新生成一個下載器 SDWebImageDownloader 開始下載圖片。
10. 圖片下載由 NSURLConnection 來做,實現(xiàn)相關(guān) delegate 來判斷圖片下載中、下載完成和下載失敗。
11. connection:didReceiveData: 中利用 ImageIO 做了按圖片下載進度加載效果。
12. connectionDidFinishLoading: 數(shù)據(jù)下載完成后交給 SDWebImageDecoder 做圖片解碼處理。
13. 圖片解碼處理在一個 NSOperationQueue 完成,不會拖慢主線程 UI。如果有需要對下載的圖片進行二次處理,最好也在這里完成,效率會好很多。
14. 在主線程 notifyDelegateOnMainThreadWithInfo: 宣告解碼完成,imageDecoder:didFinishDecodingImage:userInfo: 回調(diào)給 SDWebImageDownloader。
15. imageDownloader:didFinishWithImage: 回調(diào)給 SDWebImageManager 告知圖片下載完成。
16. 通知所有的 downloadDelegates 下載完成,回調(diào)給需要的地方展示圖片。
17. 將圖片保存到 SDImageCache 中,內(nèi)存緩存和硬盤緩存同時保存。寫文件到硬盤也在以單獨 NSInvocationOperation 完成,避免拖慢主線程。
18. SDImageCache 在初始化的時候會注冊一些消息通知,在內(nèi)存警告或退到后臺的時候清理內(nèi)存圖片緩存,應(yīng)用結(jié)束的時候清理過期圖片。
19. SDWI 也提供了 UIButton+WebCache 和 MKAnnotationView+WebCache,方便使用。
20. SDWebImagePrefetcher 可以預(yù)先下載圖片,方便后續(xù)使用。
從上面流程可以看出,當(dāng)你調(diào)用setImageWithURL:方法的時候,他會自動去給你干這么多事,當(dāng)你需要在某一具體時刻做事情的時候,你可以覆蓋這些方法。比如在下載某個圖片的過程中要響應(yīng)一個事件,就覆蓋這個方法:
//覆蓋方法,指哪打哪,這個方法是下載imagePath2的時候響應(yīng)
SDWebImageManager *manager = [SDWebImageManager sharedManager];
[manager downloadImageWithURL:imagePath2 options:SDWebImageRetryFailed progress:^(NSInteger receivedSize, NSInteger expectedSize) {
NSLog(@"顯示當(dāng)前進度");
} completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
NSLog(@"下載完成");
}];
對于初級來說,用sd_setImageWithURL:的若干個方法就可以實現(xiàn)很好的圖片緩存。
http://www.cocoachina.com/ios/20141212/10622.html
屬性相關(guān)的關(guān)鍵字,可以按照一些功能來分類
線程相關(guān)
atomic:默認(rèn)為該屬性,功能為在多線程的情況下,編譯器自動生成相應(yīng)的線程安全代碼,達到互斥加鎖的目的,避免所對應(yīng)的變量出現(xiàn)讀寫不同步的問題。
nonatomic:當(dāng)該變量不需要考慮多線程的情況時使用該關(guān)鍵字,能夠提高性能和效率。
atomic主要用于線程保護的,可以避免當(dāng)一個線程在對一個地址進行訪問時防止另一個線程對此地址同時進行訪問,防止了數(shù)據(jù)錯誤。眾所周知,線程鎖會耗費系統(tǒng)資源,所以在實際使用時,如果沒有線程相關(guān)的內(nèi)容,建議使用nonatomic。
目前大部分的iOS app中,nonatomic的普遍使用也是基于性能考慮的。
讀寫相關(guān)
readwrite:默認(rèn)類型,會自動生成相應(yīng)的讀寫方法。
readonly:只生成相應(yīng)的get方法,不生成set方法。
主要使用目的:控制外部類對該屬性的訪問權(quán)限。
內(nèi)存引用相關(guān)
這里又根據(jù)系統(tǒng)版本分為兩類,一類是iOS 5.0之前,一類是iOS 5.0加入了ARC機制之后。
ARC之前
assgin:默認(rèn)類型,set方法中為直接賦值,即直接指向了一個地址,沒有任何引用計數(shù)的更改。
retain:set方法中,首先釋放(release)之前的對象,即去除對于舊對象的引用計數(shù),并直接指向新的對象的地址,并使新對象的引用計數(shù)加一。
copy:set方法中,與retain類似,先release舊對象,然后對于新的對象進行copy,實質(zhì)為使用新的內(nèi)存空間和地址,引用計數(shù)唯一,并將目標(biāo)對象的內(nèi)容拷貝過來。可以認(rèn)為是內(nèi)容拷貝。
ARC之后
weak:弱引用,與assgin類似,只是當(dāng)對象釋放后,weak類型會自動置空,即將指針設(shè)為nil,避免野指針。
strong:強引用,默認(rèn)類型,與retain類似。
內(nèi)存計數(shù)方面的關(guān)鍵字是objc主要內(nèi)容。
CALayer和UIView的區(qū)別聯(lián)系
1 UIView是UIKIt的只能在iOS使用, CALayer是QuartzCore的 iOS和mac os通用
2 CALayer比UIView更加輕量級,但是可以實現(xiàn)同樣的效果
3 UIView的CALayer類似UIView的子View樹形結(jié)構(gòu)
4 UIView比CALayer多了一個事件處理功能,也就是說UIView能處理用戶觸摸
5 UIView有個重要的屬性layer,可以返回它的主CALayer實例.CALayer *layer = myView.layer
6 坐標(biāo)系統(tǒng): CALayer的坐標(biāo)系統(tǒng)比UIView多了一個anchorPoint屬性
8 渲染 當(dāng)更新層 改變不能立即顯示在屏幕上.當(dāng)所有的層都準(zhǔn)備好時,可以調(diào)用setNeedsDisplay方法來重繪顯示.
9 變換 要在一個層中添加一個3D或仿射變換,可以分別設(shè)置層的transform或者affineTransform屬性
10 變形Quartz Core的渲染能力 使二維圖像可以被自由的操縱,就像是三維的.圖像可以在一個三維坐標(biāo)系中以任意的角度被旋轉(zhuǎn) 縮放 和傾斜.CATransform3D的一套方法提供了一些魔術(shù)般的效果
簡述同步和異步
同步:串行的執(zhí)行任務(wù) 異步:并行的執(zhí)行任務(wù).同步函數(shù)不具備開啟線程的能力,而異步函數(shù)具備
所謂同步,就是在發(fā)出一個調(diào)用時,在沒有得到結(jié)果之前,該調(diào)用就不返回.但是一旦調(diào)用返回,就得到返回值了.也就是 由調(diào)用者主動等待這個調(diào)用結(jié)果。而異步則是相反,調(diào)用在發(fā)出之后,這個調(diào)用就直接返回了,所以沒有返回結(jié)果.換句話說就是當(dāng)一個異步過程調(diào)用發(fā)出后,調(diào)用者不會立刻得到結(jié)果。而是在調(diào)用發(fā)出后,被調(diào)用者通過狀態(tài)、通知來通知調(diào)用者,或通過回調(diào)函數(shù)處理這個調(diào)用.
多線程安全怎么控制?
用互斥鎖,隊列組,柵欄函數(shù),依賴
什么時候使用繼承,什么時候使用類別
在OC中,一個類繼承另一個類,就是繼承了父類所有的屬性和方法,并且可以擴充自己的屬性:而類別是在不改變原有類的基礎(chǔ)上進行方法擴充;
因此,根據(jù)開發(fā)需求,如果這個類需要擴充屬性,或者需要重寫系統(tǒng)的類的某些方法,用繼承;如果只是對一個類擴充接口和模塊,使用類別更加方便.
關(guān)鍵字const有什么含意?修飾類呢?static的作用,用于類呢?還有extern c的作用?
當(dāng)使用 const修飾基數(shù)數(shù)據(jù)類型變量時,該變量就變?yōu)槌A?進入靜態(tài)區(qū)
當(dāng)使用const修飾指針類型變量時:
當(dāng)使用const在指針類型兩邊,那么該指針變量指向的內(nèi)存空間的內(nèi)容就不能改變了,但指針的指向可以改變.
如果const在變量的左邊,那么該指針的指向不能改變了,而指向內(nèi)存空間的內(nèi)容可以改變
當(dāng)使用const修飾符時,const NSSting *str,相當(dāng)于修飾該對象,表示對象是不可更改的.
static修飾變量,表示這個內(nèi)部全局變量,只能在本文件中訪問.系統(tǒng)會將該變量放進靜態(tài)區(qū),它的生命周期被延長到了程序結(jié)束
static修飾類, 表示這個內(nèi)部的方法, 只能在本文件中訪問.
extern c表示聲明了一外部變量, 多個外部變量如果同名,實際指向的是同一塊存儲空間.
UIView從出現(xiàn)到銷毀的過程?
loadView
viewDidLoad
viewWillAppear
viewWillLayoutSubviews
viewDidlayoutSubviews
viewDidAppear
viewWillDisappear
viewDidDisappear
frame和bounds有什么不同
frame的位置是相對父空間的左上角來說的 參照的是父類的坐標(biāo)系,指的是空間在父控件內(nèi)的位置和大小
bounds的位置是相對控件自身的左上角來說的,參照的是自身坐標(biāo)系,指的是自己本身的大小
NSTimer和GCD的定時器有什么區(qū)別
NSTimer 可以調(diào)用invalidate進行撤銷,創(chuàng)建和撤銷必須在同一線程
NSTimer需要交定時器添加到當(dāng)前的runloop中
它的時間單位是秒
GCD一旦執(zhí)行就不能撤銷
GCD中的定時器不受runloop模式的影響
時間單位是納秒
應(yīng)用程序的沙盒下,都有哪些文件夾?它們有什么特點?本地緩存一般存在哪個文件下?
1 Documents
將應(yīng)用程序的數(shù)據(jù)文件保存在該目錄下.不過這些數(shù)據(jù)類型僅限于不可以再生的數(shù)據(jù),可再生的數(shù)據(jù)文件應(yīng)該存在LIbrary/Cache下
2 Library 它有兩個子文件
caches 主要是緩存文件,用戶使用過程中緩存都可以保存在這些目錄中.保存那些可再生的文件,比如網(wǎng)絡(luò)數(shù)據(jù)請求.因此,應(yīng)用程序通常還需要負(fù)責(zé)刪除這些文件.
Preferences 應(yīng)用程序的偏好設(shè)置文件. 我們使用NSUserDefaults寫的設(shè)置數(shù)據(jù)都會保存到該目錄下的一個plist文件中 它會被iTunes同步
3. tmp
各種臨時文件, 保存應(yīng)用再次啟動時不需要的文件.而且,當(dāng)應(yīng)用不在需要這些文件時應(yīng)主動將其刪除,因為該目錄下的東西隨時有可能被系統(tǒng)清除,目前已知的一種可能清理的原因是系統(tǒng)磁盤存儲空間不足的時候
__weak什么時候用?
當(dāng)兩個對象互相引用的時候,一端用strong,另一端必須用weak .例如: A擁有B, B也擁有A, 那么必須一方使用weak
一般UI控件都可以使用weak,因為自身已經(jīng)對它進行一次強引用,沒有必要再強引用一次.
Object-c的類可以多重繼承么?可以實現(xiàn)多個接口么?Category是什么?重寫一個類的方式用繼承好還是分類好?為什么?
Object-c的類不可以多重繼承;可以實現(xiàn)多個接口,通過實現(xiàn)多個接口可以完成C++的多重繼承;Category是類別,一般情況用分類好,用Category去重寫類的方法,僅對本Category有效,不會影響到其他類與原有類的關(guān)系。
寫一個setter方法用于完成@property (nonatomic,retain)NSString *name,寫一個setter方法用于完成@property(nonatomic,copy)NSString *name
- (void) setName:(NSString*) str
{
[str retain];
[name release];
name = str;
}
- (void)setName:(NSString *)str
{
id t = [str copy];
[name release];
name = t;
}
Object C中創(chuàng)建線程的方法是什么?如果在主線程中執(zhí)行代碼,方法是什么?如果想延時執(zhí)行代碼、方法又是什么?
線程創(chuàng)建有三種方法:使用NSThread創(chuàng)建、使用GCD的dispatch、使用子類化的NSOperation,然后將其加入NSOperationQueue;在主線程執(zhí)行代碼,方法是performSelectorOnMainThread,如果想延時執(zhí)行代碼可以用performSelector:onThread:withObject:waitUntilDone:
類別的作用?繼承和類別在實現(xiàn)中有何區(qū)別?
category 可以在不獲悉,不改變原來代碼的情況下往里面添加新的方法,只能添加,不能刪除修改,并且如果類別和原來類中的方法產(chǎn)生名稱沖突,則類別將覆蓋原來的方法,因為類別具有更高的優(yōu)先級。
類別主要有3個作用1).將類的實現(xiàn)分散到多個不同文件或多個不同框架中。2).創(chuàng)建對私有方法的前向引用。3).向?qū)ο筇砑臃钦絽f(xié)議。繼承可以增加,修改或者刪除方法,并且可以增加屬性。
什么是KVO和KVC?
VC:鍵 – 值編碼是一種間接訪問對象的屬性使用字符串來標(biāo)識屬性,而不是通過調(diào)用存取方法,直接或通過實例變量訪問的機制。
KVO:鍵值觀察機制,他提供了觀察某一屬性變化的方法,極大的簡化了代碼 比如我自定義的一個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:
“當(dāng)通過KVC調(diào)用對象時,比如:[self valueForKey:@”someKey”]時,程序會自動試圖通過幾種不同的方式解析這個調(diào)用。首先查找對象是否帶有 someKey 這個方法,如果沒找到,會繼續(xù)查找對象是否帶有someKey這個實例變量(iVar),如果還沒有找到,程序會繼續(xù)試圖調(diào)用 -(id) valueForUndefinedKey:這個方法。如果這個方法還是沒有被實現(xiàn)的話,程序會拋出一個NSUndefinedKeyException異常錯誤。設(shè)計valueForUndefinedKey:方法的主要目的是當(dāng)你使用-(id)valueForKey方法從對象中請求值時,對象能夠在錯誤發(fā)生前,有最后的機會響應(yīng)這個請求。這樣做有很多好處,下面的兩個例子說明了這樣做的好處?!?
對于單例的理解
在objective-c中要實現(xiàn)一個單例類,至少需要做以下四個步驟:
1).為單例對象實現(xiàn)一個靜態(tài)實例,并初始化,然后設(shè)置成nil,
2).實現(xiàn)一個實例構(gòu)造方法檢查上面聲明的靜態(tài)實例是否為nil,如果是則新建并返回一個本類的實例,
3).重寫allocWithZone方法,用來保證其他人直接使用alloc和init試圖獲得一個新實力的時候不產(chǎn)生一個新實例,
4).適當(dāng)實現(xiàn)allocWitheZone,copyWithZone,release和autorelease。
并行(Concurrent) & 串行(Serial)
并行和串行描述的是任務(wù)和任務(wù)之間的執(zhí)行方式,并行是任務(wù)A和任務(wù)B可以同時執(zhí)行,串行是任務(wù)A執(zhí)行完了任務(wù)B才能執(zhí)行(按順序執(zhí)行)。
異步(Asynchronous) & 同步(Synchronous)
異步和同步描述的其實就是函數(shù)什么時候返回. 比如用來下載圖片的函數(shù): 同步函數(shù)只有在image下載結(jié)束之后才返回, 下載的這段時間函數(shù)只能等待,而異步函數(shù),不會去等它完成(異步函數(shù)不會堵塞當(dāng)前線程去執(zhí)行下一個函數(shù))。
并發(fā)(Concurrency) & 并行(Parallelism)
這個更容易混淆了, 并發(fā)和并行都是用來讓不同的任務(wù)可以"同時執(zhí)行"。 只是并行是真同時,而并發(fā)是假同時(是CPU地在各個進程之間快速切換, 給人一種能同時處理多任務(wù)的錯覺)。
CAAnimation繼承結(jié)構(gòu)
