今後走上一條iOS程序猿不歸路。。。

新的城市,新的生活!前不久剛剛結束了苦逼的面試找工做之旅,期間也小有收貨,現在正處年末工做閒暇之餘,將前一陣子陸陸續續的總結整理了一下,本人菜鳥程序猿一隻,水平有限,本文總結的知識不算深刻,比較淺顯,還望大神見諒,重在總結,交流與分享。。。-_-!
文章主要宗旨以下:
  • 1:ios開發中常見技術的總結(主要是區別)
  • 2:做爲一個iOS程序員必備的常識問題
  • 3:做爲面試必備的一份寶典
  • 4:初學者快速瞭解相關技術
  • 5:老程序員快速回顧混淆,忘記的知識點

後續我也會一直講本文更新下去,有遺漏點或者錯誤的地方望指出,或者聯繫我,相互交流技術,謝謝!ios

好了開始吧。。。。。。。。。。。git

一: weak&strong

  • strong表示保留它指向的堆上的內存區域再也不指向這塊區域了。 也就是說我強力指向了一個區域,咱們再也不指向它的條件只有咱們指向nil或者我本身也不在內存上,沒有人strong指向我了。
  • weak表示若是尚未人指向它了,它就會被清除內存,同時被指向nil,由於我不能讀取不存在的東西。程序員

    weak只在iOS5.0使用

這並非垃圾回收,咱們用reference count 表示堆上還有多少strong指針,當它變爲0就立刻釋放。github

本地變量都是strong,編輯器幫你計算.面試

補充算法

  • 管理機制:使用了一種叫作引用計數的機制來管理內存中的對象。OC中每一個對象都對應着他們本身的引用計數,引用計數能夠理解爲一個整數計數器,當使 用alloc方法建立對象的時候,持有計數會自動設置爲1。當你向一個對象發送retain消息 時,持有計數數值會增長1。相反,當你像一個對象發送release消息時,持有計數數值會減少1。當對象的持有計數變爲0的時候,對象會釋放本身所佔用 的內存。 retain(引用計數加1)->release(引用計數減1) alloc(申請內存空間)->dealloc(釋放內存空間) readwrite: 表示既有getter,也有setter (默認) readonly: 表示只有getter,沒有setter nonatomic:不考慮線程安全 atomic:線程操做安全 (默認) 線程安全狀況下的setter和getter:sql

    • (NSString*) value { @synchronized(self) { return [[_value retain] autorelease];
      } }
    • (void) setValue:(NSString)aValue { @synchronized(self) { [aValue retain]; [value release]; value = aValue;
      } } retain: release舊的對象,將舊對象的值賦予輸入對象,再提升輸入對象的索引計數爲1 assign: 簡單賦值,不更改索引計數 (默認) copy: 實際上是創建了一個相同的對象,地址不一樣(retain:指針拷貝 copy:內容拷貝) strong:(ARC下的)和(MRC)retain同樣 (默認) weak:(ARC下的)和(MRC)assign同樣, weak當指向的內存釋放掉後自動nil化,防止野指針 unsafe_unretained 聲明一個弱應用,可是不會自動nil化,也就是說,若是所指向的內存區域被釋放了,這個指針就是一個野指針了。 autoreleasing 用來修飾一個函數的參數,這個參數會在函數返回的時候被自動釋放。一、 類變量的@protected ,@private,@public,@package,聲明各有什麼含義? @private:做用範圍只能在自身類 @protected:做用範圍在自身類和繼承本身的子類 (默認) @public:做用範圍最大,能夠在任何地方被訪問。 @package:這個類型最經常使用於框架類的實例變量,同一包內能用,跨包就不能訪問

二: category&extension

類別主要有三個做用數據庫

  • (1)能夠將類的實現分散到多個不一樣文件或多個不一樣框架中,方便代碼管理。也能夠對框架提供類的擴展(沒有源碼,不能修改)。編程

  • (2)建立對私有方法的前向引用:若是其餘類中的方法未實現,在你訪問其餘類的私有方法時編譯器報錯這時使用類別,在類別中聲明這些方法(沒必要提供方法實現),編譯器就不會再產生警告後端

  • (3)向對象添加非正式協議:建立一個NSObject的類別稱爲「建立一個非正式協議」,由於能夠做爲任何類的委託對象使用。

    他們的主要區別是:

  • 一、形式上來看,extension是匿名的category。

  • 二、extension裏聲明的方法須要在mainimplementation中實現,category不強制要求。

  • 三、extension能夠添加屬性(變量),category不能夠。

    Category和Extension都是用來給已定義的類增長新的內容的。

  • Category和原有類的耦合更低一些,聲明和實現均可以寫在單獨的文件裏。可是隻能爲已定義類增長Method,而不能加入instance variable。

  • Extension耦合比較高,聲明能夠單獨寫,可是實現必須寫在原有類的@implementation中。能夠增長Method和instance variable。

  • Extension給人感受更像是在編寫類時爲了封裝之類的特性而設計,和類是同時編寫的。而category則是在用到某一個framework中的類時臨時增長的特性。

  • Extension的一個特性就是能夠redeclare一個instance variable,將之從readonly改成對內readwrite.

    使用Extension能夠更好的封裝類,在h文件中能看到的都是對外的接口,其他的instance variable和對內的@property等均可以寫在Extension,這樣類的結構更加清晰。

三: define&const

  • define在預處理階段進行替換,const常量在編譯階段使用 宏不作類型檢查,僅僅進行替換,const常量有數據類型,會執行類型檢查 define不能調試,const常量能夠調試 define定義的常量在替換後運行過程當中會不斷地佔用內存,而const定義的常量存儲在數據段只有一份copy,效率更高 define能夠定義一些簡單的函數,const不能夠

四: synthesize&denamic

  • 1:經過@synthesize 指令告訴編譯器在編譯期間產生getter/setter方法。
  • 2: 經過@dynamic指令,本身實現方法。

    有些存取是在運行時動態建立的,如在CoreData的NSManagedObject類使用的某些。若是你想這些狀況下,聲明和使用屬性,但要避免缺乏方法在編譯時的警告,你能夠使用@dynamic動態指令,而不是@synthesize合成指令。

五: UIView的setNeedsDisplay和setNeedsLayout方法

  • 一、在Mac OS中NSWindow的父類是NSResponder,而在i OS 中UIWindow 的父類是UIVIew。程序通常只有一個窗口可是會又不少視圖。

  • 二、UIView的做用:描畫和動畫,視圖負責對其所屬的矩形區域描畫、佈局和子視圖管理、事件處理、能夠接收觸摸事件、事件信息的載體、等等。

  • 三、UIViewController 負責建立其管理的視圖及在低內存的時候將他們從內存中移除。還爲標準的系統行爲進行響應。

  • 四、layOutSubViews 能夠在本身定製的視圖中重載這個方法,用來調整子視圖的尺寸和位置。

  • 五、UIView的setNeedsDisplay和setNeedsLayout方法。首先兩個方法都是異步執行的。而 setNeedsDisplay會調用自動調用drawRect方法,這樣能夠拿到UIGraphicsGetCurrentContext,就能夠畫畫 了。而setNeedsLayout會默認調用layoutSubViews,就能夠處理子視圖中的一些數據。

綜上所述:setNeedsDisplay方便繪圖,而layoutSubViews方便出來數據

setNeedDisplay告知視圖它發生了改變,須要從新繪製自身,就至關於刷新界面.

六: UILayer&UIView

  1. UIView是iOS系統中界面元素的基礎,全部的界面元素都繼承自它。它自己徹底是由CoreAnimation來實現的(Mac下彷佛不是這 樣)。它真正的繪圖部分,是由一個叫CALayer(Core Animation Layer)的類來管理。UIView自己,更像是一個CALayer的管理器,訪問它的跟繪圖和跟座標有關的屬性,例如frame,bounds等等, 實際上內部都是在訪問它所包含的CALayer的相關屬性。

  2. UIView有個重要屬性layer,能夠返回它的主CALayer實例。

  3. UIView的CALayer相似UIView的子View樹形結構,也能夠向它的layer上添加子layer,來完成某些特殊的表示。即CALayer層是能夠嵌套的。

  4. UIView的layer樹形在系統內部,被維護着三份copy。分別是邏輯樹,這裏是代碼能夠操縱的;動畫樹,是一箇中間層,系統就在這一層上更改屬性,進行各類渲染操做;顯示樹,其內容就是當前正被顯示在屏幕上得內容。

  5. 動畫的運做:對UIView的subLayer(非主Layer)屬性進行更改,系統將自動進行動畫生成,動畫持續時間的缺省值彷佛是0.5秒。

  6. 座標系統:CALayer的座標系統比UIView多了一個anchorPoint屬性,使用CGPoint結構表示,值域是0~1,是個比例值。

  7. 渲染:當更新層,改變不能當即顯示在屏幕上。當全部的層都準備好時,能夠調用setNeedsDisplay方法來重繪顯示。

  8. 變換:要在一個層中添加一個3D或仿射變換,能夠分別設置層的transform或affineTransform屬性。

  9. 變形:Quartz Core的渲染能力,使二維圖像能夠被自由操縱,就好像是三維的。圖像能夠在一個三維座標系中以任意角度被旋轉,縮放和傾斜。CATransform3D的一套方法提供了一些魔術般的變換效果。

七: UITableView&UICollection

UICollectionView是iOS6新引進的API,用於展現集合視圖,佈局更加靈活,其用法相似於UITableView。而 UICollectionView、UICollectionViewCell與UITableView、UITableViewCell在用法上有類似 的也有不一樣的,下面是一些基本的使用方法:

對於UITableView,僅須要UITableViewDataSource,UITableViewDelegate這兩個協議,使用 UICollectionView須要實現UICollectionViewDataSource, UICollectionViewDelegate,UICollectionViewDelegateFlowLayout這三個協議,這是由於 UICollectionViewDelegateFlowLayout其實是UICollectionViewDelegate的一個子協議,它繼承 了UICollectionViewDelegate,它的做用是提供一些定義UICollectionView佈局模式的函數

八:NSProxy&NSObject

NSObjetc:

NSObject協議組對全部的Object-C下的objects都生效。 若是objects聽從該協議,就會被看做是first-class objects(一級類)。 另外,聽從該協議的objects的retain,release,autorelease等方法也服從objects的管理和在Foundation中 定義的釋放方法。一些容器中的對象也能夠管理這些objects,好比 說NSArray 和NSDictionary定義的對象。 Cocoa的根類也遵循該協議,因此全部繼承NSObjects的objects都有遵循該協議的特性。

NSProXY:

NSProxy 是一個虛基類,它爲一些表現的像是其它對象替身或者並不存在的對象定義一套API。通常的,發送給代理的消息被轉發給一個真實的對象或者代理自己 load(或者將自己轉換成)一個真實的對象。NSProxy的基類能夠被用來透明的轉發消息或者耗費巨大的對象的lazy 初始化。

九: layoutSubViews&drawRects

layoutSubviews在如下狀況下會被調用:

  • 一、init初始化不會觸發layoutSubviews。
  • 二、addSubview會觸發layoutSubviews。
  • 三、設置view的Frame會觸發layoutSubviews,固然前提是frame的值設置先後發生了變化。
  • 四、滾動一個UIScrollView會觸發layoutSubviews。
  • 五、旋轉Screen會觸發父UIView上的layoutSubviews事件。
  • 六、改變一個UIView大小的時候也會觸發父UIView上的layoutSubviews事件。
  • 七、直接調用setLayoutSubviews。

drawRect在如下狀況下會被調用:

  • 一、若是在UIView初始化時沒有設置rect大小,將直接致使drawRect不被自動調用。drawRect 掉用是在Controller->loadView, Controller->viewDidLoad 兩方法以後掉用的.因此不用擔憂在 控制器中,這些View的drawRect就開始畫了.這樣能夠在控制器中設置一些值給View(若是這些View draw的時候須要用到某些變量 值).
  • 二、該方法在調用sizeToFit後被調用,因此能夠先調用sizeToFit計算出size。而後系統自動調用drawRect:方法。
  • 三、經過設置contentMode屬性值爲UIViewContentModeRedraw。那麼將在每次設置或更改frame的時候自動調用drawRect:。
  • 四、直接調用setNeedsDisplay,或者setNeedsDisplayInRect:觸發drawRect:,可是有個前提條件是rect不能爲0。

drawRect方法使用注意點:

  • 一、 若使用UIView繪圖,只能在drawRect:方法中獲取相應的contextRef並繪圖。若是在其餘方法中獲取將獲取到一個invalidate 的ref而且不能用於畫圖。drawRect:方法不能手動顯示調用,必須經過調用setNeedsDisplay 或 者 setNeedsDisplayInRect,讓系統自動調該方法。

  • 二、若使用calayer繪圖,只能在drawInContext: 中(相似魚drawRect)繪製,或者在delegate中的相應方法繪製。一樣也是調用setNeedDisplay等間接調用以上方法 三、若要實時畫圖,不能使用gestureRecognizer,只能使用touchbegan等方法來掉用setNeedsDisplay實時刷新屏幕

十:NSCache&NSDcitionary

NSCache與可變集合有幾點不一樣:

  • NSCache類結合了各類自動刪除策略,以確保不會佔用過多的系統內存。若是其它應用須要內存時,系統自動執行這些策略。當調用這些策略時,會從緩存中刪除一些對象,以最大限度減小內存的佔用。
  • NSCache是線程安全的,咱們能夠在不一樣的線程中添加、刪除和查詢緩存中的對象,而不須要鎖定緩存區域。
  • 不像NSMutableDictionary對象,一個緩存對象不會拷貝key對象。

NSCache和NSDictionary相似,不一樣的是系統回收內存的時候它會自動刪掉它的內容。

  • (1)能夠存儲(固然是使用內存)
  • (2)保持強應用, 無視垃圾回收. =>這一點同 NSMutableDictionary
  • (3)有固定客戶.

十一:AFNetworking&ASIHttpRequest&MKNetWorking

1、底層實現

一、AFN的底層實現基於OC的NSURLConnection和NSURLSession 二、ASI的底層實現基於純C語言的CFNetwork框架 三、由於NSURLConnection和NSURLSession是在CFNetwork之上的一層封裝,所以ASI的運行性能高於AFN

AFNetworking的下載地址: https://github.com/AFNetworking/AFNetworking

2、對服務器返回的數據處理

一、ASI沒有直接提供對服務器數據處理的方式,直接返回的是NSData/NSString 二、AFN提供了多種對服務器數據處理的方式 (1)JSON處理-直接返回NSDictionary或者NSArray (2)XML處理-返回的是xml類型數據,需對其進行解析 (3)其餘類型數據處理

3、監聽請求過程

一、AFN提供了success和failure兩個block來監聽請求的過程(只能監聽成功和失敗)
* success : 請求成功後調用 * failure : 請求失敗後調用 二、ASI提供了3套方案,每一套方案都能監聽請求的完整過程 (監聽請求開始、接收到響應頭信息、接受到具體數據、接受完畢、請求失敗) * 成爲代理,遵照協議,實現協議中的代理方法 * 成爲代理,不遵照協議,自定義代理方法 * 設置block

4、在文件下載和文件上傳的使用難易度

一、AFN *不容易實現監聽下載進度和上傳進度 *不容易實現斷點續傳 *通常只用來下載不大的文件 二、ASI *很是容易實現下載和上傳 *很是容易監聽下載進度和上傳進度 *很是容易實現斷點續傳 *下載大文件或小文件都可 三、實現下載上傳推薦使用ASI

5、網絡監控

一、AFN本身封裝了網絡監控類,易使用 二、ASI使用的是Reachability,由於使用CocoaPods下載ASI時,會同步下載Reachability,但Reachability做爲網絡監控使用較爲複雜(相對於AFN的網絡監控類來講) 三、推薦使用AFN作網絡監控-AFNetworkReachabilityManager

6、ASI提供的其餘實用功能

一、控制信號旁邊的圈圈要不要在請求過程當中轉 二、能夠輕鬆地設置請求之間的依賴:每個請求都是一個NSOperation對象 三、能夠統一管理全部請求(還專門提供了一個叫作ASINetworkQueue來管理全部的請求對象) * 暫停/恢復/取消全部的請求 * 監聽整個隊列中全部請求的下載進度和上傳進度

MKNetworkKit 是一個使用十分方便,功能又十分強大、完整的iOS網絡編程代碼庫。它只有兩個類, 它的目標是使用像AFNetworking這麼簡單,而功能像ASIHTTPRequest(已經中止維護)那麼強大。它除了擁有 AFNetworking和ASIHTTPRequest全部功能之外,還有一些新特點,包括:

  • 一、高度的輕量級,僅僅只有2個主類

  • 二、自主操做多個網絡請求

  • 三、更加準確的顯示網絡活動指標

  • 四、自動設置網絡速度,實現自動的2G、3G、wifi切換

  • 五、自動緩衝技術的完美應用,實現網絡操做記憶功能,當你掉線了又上線後,會繼續執行未完成的網絡請求

  • 六、能夠實現網絡請求的暫停功能

  • 七、準確無誤的成功執行一次網絡請求,摒棄後臺的屢次請求浪費

  • 八、支持圖片緩衝

  • 九、支持ARC機制

  • 十、在整個app中能夠只用一個隊列(queue),隊列的大小能夠自動調整


十二:load&initialize

  • (void)load;
  • (void)initialize;

能夠看到這兩個方法都是以「+」開頭的類方法,返回爲空。一般狀況下,咱們在開發過程當中可能沒必要關注這兩個方法。若是有須要定製,咱們能夠在自定義的NSObject子類中給出這兩個方法的實現,這樣在類的加載和初始化過程當中,自定義的方法能夠獲得調用。

load和initialize的共同特色

  • 在不考慮開發者主動使用的狀況下,系統最多會調用一次

  • 若是父類和子類都被調用,父類的調用必定在子類以前

  • 都是爲了應用運行提早建立合適的運行環境

  • 在使用時都不要太重地依賴於這兩個方法,除非真正必要

    它們的相同點在於:方法只會被調用一次。(其實這是相對runtime來講的,後邊會作進一步解釋)。
    
      The runtime sends initialize to each class in a program exactly one time just before the class, or any class that inherits from it, is sent its first message from within the program. (Thus the method may never be invoked if the class is not used.) The runtime sends the initialize message to classes in a thread-safe manner. Superclasses receive this message before their subclasses.
    
      The load message is sent to classes and categories that are both dynamically loaded and statically linked, but only if the newly loaded class or category implements a method that can respond.
  • load是隻要類所在文件被引用就會被調用,而initialize是在類或者其子類的第一個方法被調用前調用。因此若是類沒有被引用進項目,就不會有load調用;但即便類文件被引用進來,可是沒有使用,那麼initialize也不會被調用。

  • 文檔也明確闡述了方法調用的順序:父類(Superclass)的方法優先於子類(Subclass)的方法,類中的方法優先於類別(Category)中的方法。

十三:ARC-Block&MRC-Block

block雖然好用,可是裏面也有很多坑,最大的坑莫過於循環引用問題。稍不注意,可能就會形成內存泄漏。這節,我將從源碼的角度來分析形成循環引用問題的根本緣由。並解釋變量前加block,和weak的區別。

明確兩點

1,Block能夠訪問Block函數以及語法做用域之內的外部變量。也就是說:一個函數裏定義了個block,這個block能夠訪問該函數的內 部變量(固然還包括靜態,全局變量)-即block能夠使用和自己定義範圍相同的變量。 2,Block實際上是特殊的Objective-C對象,能夠使用copy,release等來管理內存,但和通常的NSObject的管理方式有些不 同,稍後會說明。

MRC:防止 block 對self的引用 解決辦法

__block typeof(self) weakSelf = self;

ARC:防止 block 對self的引用 解決辦法

__weak typeof(self) weakSelf = self;

對於非ARC下, 爲了防止循環引用, 咱們使用__block來修飾在Block中使用的對象:

對於ARC下, 爲了防止循環引用, 咱們使用weak來修飾在Block中使用的對象。原理就是:ARC中,Block中若是引用了strong修飾符的自動變量,則至關於Block對該變量的引用計數+1。

十四:MVC&MVVM

  • 在MVC裏,View是能夠直接訪問Model的!從而,View裏會包含Model信息,不可避免的還要包括一些業務邏輯。 MVC模型關注的是Model的不變,因此,在MVC模型裏,Model不依賴於View,可是 View是依賴於Model的。不只如此,由於有一些業務邏輯在View裏實現了,致使要更改View也是比較困難的,至少那些業務邏輯是沒法重用的。

  • MVVM在概念上是真正將頁面與數據邏輯分離的模式,它把數據綁定工做放到一個JS裏去實現,而這個JS文件的主要功能是完成數據的綁定,即把model綁定到UI的元素上。

    有人作過測試:使用Angular(MVVM)代替Backbone(MVC)來開發,代碼能夠減小一半。
  • 此外,MVVM另外一個重要特性,雙向綁定。它更方便你同時維護頁面上都依賴於某個字段的N個區域,而不用手動更新它們。

總結:

  • 優勢:MVVM就是在MVC的基礎上加入了一個視圖模型viewModel,用於數據有效性的驗證,視圖的展現邏輯,網絡數據請求及處理,其餘的 數據處理邏輯集合,並定下相關接口和協議。相比起MVC,MVVM中vc的職責和複雜度更小,對數據處理邏輯的測試更加方便,對bug的緣由排查更加方 便,代碼可閱讀性,重用性和可維護性更高。MVVM耦合性更低。MVVM不一樣層級的職責更加明確,更有利於代碼的編寫和團隊的協做。 缺點:MVVM相比MVC代碼量有所增長。MVVM相比MVC在代碼編寫以前須要有更清晰的模式思路。

十五:Object&Swift

Obejective-C複雜的語法,更加簡單易用、有將來,讓許多開發者心動不已,Swift明顯的特色有:

  • 蘋果宣稱 Swift 的特色是:快速、現代、安全、互動,並且明顯優於 Objective-C 語言

  • 能夠使用現有的 Cocoa 和 Cocoa Touch 框架

  • Swift 取消了 Objective C 的指針及其餘不安全訪問的使用

  • 捨棄 Objective C 早期應用 Smalltalk 的語法,全面改成句點表示法

  • 提供了相似 Java 的名字空間(namespace)、泛型(generic)、運算對象重載(operator overloading)

  • Swift 被簡單的形容爲 「沒有 C 的 Objective-C」(Objective-C without the C)

  • 爲蘋果開發工具帶來了Xcode Playgrounds功能,該功能提供強大的互動效果,能讓Swift源代碼在撰寫過程當中實時顯示出其運行結果;

  • 基於C和Objective-C,而卻沒有C的一些兼容約束;

  • 採用了安全的編程模式;

  • 界面基於Cocoa和Cocoa Touch框架;

  • 保留了Smalltalk的動態特性。

十六:TCP&UDP

  • TCP(Transmission Control Protocol,傳輸控制協議)是基於鏈接的協議,也就是說,在正式收發數據前,必須和對方創建可靠的鏈接。一個TCP鏈接必需要通過三次「對話」才能 創建起來,其中的過程很是複雜,咱們這裏只作簡單、形象的介紹,你只要作到可以理解這個過程便可。

  • UDP(User Data Protocol,用戶數據報協議)是與TCP相對應的協議。它是面向非鏈接的協議,它不與對方創建鏈接,而是直接就把數據包發送過去! UDP適用於一次只傳送少許數據、對可靠性要求不高的應用環境。


十七:POST&GET

  1. get是從服務器上獲取數據,post是向服務器傳送數據。
  2. get是把參數數據隊列加到提交表單的ACTION屬性所指的URL中,值和表單內各個字段一一對應,在URL中能夠看到。post是經過 HTTP post機制,將表單內各個字段與其內容放置在HTML HEADER內一塊兒傳送到ACTION屬性所指的URL地址。用戶看不到這個過程。
  3. 對於get方式,服務器端用Request.QueryString獲取變量的值,對於post方式,服務器端用Request.Form獲取提交的數據。
  4. get傳送的數據量較小,不能大於2KB。post傳送的數據量較大,通常被默認爲不受限制。但理論上,IIS4中最大量爲80KB,IIS5中爲100KB。
  5. get安全性很是低,post安全性較高。可是執行效率卻比Post方法好。

建議: 一、get方式的安全性較Post方式要差些,包含機密信息的話,建議用Post數據提交方式; 二、在作數據查詢時,建議用Get方式;而在作數據添加、修改或刪除時,建議用Post方式;

十八:長連接&短連接

  • TCP短鏈接

    咱們模擬一下TCP短鏈接的狀況,client向server發起鏈接請求,server接到請求,而後雙方創建鏈接。client向server 發送消息,server迴應client,而後一次讀寫就完成了,這時候雙方任何一個均可以發起close操做,不過通常都是client先發起 close操做。爲何呢,通常的server不會回覆完client後當即關閉鏈接的,固然不排除有特殊的狀況。從上面的描述看,短鏈接通常只會在 client/server間傳遞一次讀寫操做

  • TCP長鏈接

    接下來咱們再模擬一下長鏈接的狀況,client向server發起鏈接,server接受client鏈接,雙方創建鏈接。Client與server完成一次讀寫以後,它們之間的鏈接並不會主動關閉,後續的讀寫操做會繼續使用這個鏈接。

    長鏈接短鏈接操做過程

短鏈接的操做步驟是:
創建鏈接——數據傳輸——關閉鏈接…創建鏈接——數據傳輸——關閉鏈接

  • 長鏈接的操做步驟是:

    創建鏈接——數據傳輸…(保持鏈接)…數據傳輸——關閉鏈接

    何時用長鏈接,短鏈接?

  • 長鏈接多用於操做頻繁,點對點的通信,並且鏈接數不能太多狀況,。每一個TCP鏈接都須要三步握手,這須要時間,若是每一個操做都是先鏈接,再操做的話 那麼處理速度會下降不少,因此每一個操做完後都不斷開,次處理時直接發送數據包就OK了,不用創建TCP鏈接。例如:數據庫的鏈接用長鏈接, 若是用短鏈接頻繁的通訊會形成socket錯誤,並且頻繁的socket 建立也是對資源的浪費。

  • 而像WEB網站的http服務通常都用短連接,由於長鏈接對於服務端來講會耗費必定的資源,而像WEB網站這麼頻繁的成千上萬甚至上億客戶端的鏈接 用短鏈接會更省一些資源,若是用長鏈接,並且同時有成千上萬的用戶,若是每一個用戶都佔用一個鏈接的話,那可想而知吧。因此併發量大,但每一個用戶無需頻繁操 做狀況下需用短連好。

    長鏈接和短鏈接的優勢和缺點

    由上能夠看出,長鏈接能夠省去較多的TCP創建和關閉的操做,減小浪費,節約時間。對於頻繁請求資源的客戶來講,較適用長鏈接。不過這裏存在一個問 題,存活功能的探測週期太長,還有就是它只是探測TCP鏈接的存活,屬於比較斯文的作法,遇到惡意的鏈接時,保活功能就不夠使了。在長鏈接的應用場景 下,client端通常不會主動關閉它們之間的鏈接,Client與server之間的鏈接若是一直不關閉的話,會存在一個問題,隨着客戶端鏈接愈來愈 多,server遲早有扛不住的時候,這時候server端須要採起一些策略,如關閉一些長時間沒有讀寫事件發生的鏈接,這樣可 以免一些惡意鏈接致使server端服務受損;若是條件再容許就能夠以客戶端機器爲顆粒度,限制每一個客戶端的最大長鏈接數,這樣能夠徹底避免某個蛋疼的 客戶端連累後端服務。

  • 短鏈接對於服務器來講管理較爲簡單,存在的鏈接都是有用的鏈接,不須要額外的控制手段。但若是客戶請求頻繁,將在TCP的創建和關閉操做上浪費時間和帶寬。

  • 長鏈接和短鏈接的產生在於client和server採起的關閉策略,具體的應用場景採用具體的策略,沒有十全十美的選擇,只有合適的選擇。

十九:內存泄露&內存溢出

  • 內存溢出 out of memory,是指程序在申請內存時,沒有足夠的內存空間供其使用,出現out of memory;好比申請了一個integer,但給它存了long才能存下的數,那就是內存溢出。

  • 內存泄露 memory leak,是指程序在申請內存後,沒法釋放已申請的內存空間,一次內存泄露危害能夠忽略,但內存泄露堆積後果很嚴重,不管多少內存,早晚會被佔光。

    memory leak會最終會致使out of memory!

內存溢出就是你要求分配的內存超出了系統能給你的,系統不能知足需求,因而產生溢出。

二十:CoreData&SQLite3

首先,coredata和sqlite的概念不一樣,core爲對象週期管理,而sqlite爲dbms。

  • 使用方便性。實際上,一個成熟的工程中必定是對數據持久化進行了封裝的,所以底層使用的究竟是core data仍是sqlite,不該該被業務邏輯開發者關心。所以,即便習慣寫SQL查詢的人,也應該避免在業務邏輯中直接編寫SQL語句。
  • 存儲性能,在寫入性能上,由於都是使用的sqlite格式做爲磁盤存儲格式,所以其性能是同樣的,若是你以爲用core data寫的慢,極可能是你用sqlite的時候寫的每條數據的內容沒有core data時多,或者是你批量寫入的時候每寫入一條就調用了一次save。
  • 查詢性能,core data由於要兼容多種後端格式,所以查詢時,其可用的語句比直接使用sqlite少,所以有些fetch實際上不是在sqlite中執行的。但這樣未必 會下降查詢效率。由於iPhone的flash memory速度仍是很快的。個人經驗是大部分時候,在內存不是很緊張時,直接fetch一個entity的全部數據而後在內存中作filter每每比使 用predicate在fetch時過濾更快。若是你覺的查詢慢,極可能是查詢方式有問題,能夠把core data的debug模式打開,看一下到底執行了多少SQL語句,相信其中大部分是能夠經過改寫core data的調用方式避免的。
  • core data的一個比較大的痛點是多人合做開發的時候,管理coredata的模型須要很當心,尤爲是合併的時候,他的data model是XML格式的,手動resolve比較煩心。
  • core data還有其餘sql所不具有的優勢,好比對undo的支持,多個context實現sketchbook相似的功能。爲ManagedObject優化的row cash等。
  • 另外core data是支持多線程的,但須要thread confinement的方式實現,使用了多線程以後能夠最大化的防止阻塞主線程。

二十一:傳值通知&推送通知(本地&遠程)

  • 傳值通知:相似通知,代理,Block實現值得傳遞
  • 推送通知:推送到用戶手機對應的App上(主要是再也不前臺的狀況)

    本地通知。

    local notification,用於基於時間行爲的通知,好比有關日曆或者todo列表的小應用。另外,應用若是在後臺執行,iOS容許它在受限的時間內運 行,它也會發現本地通知有用。好比,一個應用,在後臺運行,嚮應用的服務器端獲取消息,當消息到達時,好比下載更新版本的提示消息,經過本地通知機制通知 用戶。

    本地通知是UILocalNotification的實例,主要有三類屬性:

  • scheduled time,時間週期,用來指定iOS系統發送通知的日期和時間;

  • notification type,通知類型,包括警告信息、動做按鈕的標題、應用圖標上的badge(數字標記)和播放的聲音;
  • 自定義數據,本地通知能夠包含一個dictionary類型的本地數據。

    對本地通知的數量限制,iOS最多容許最近本地通知數量是64個,超過限制的本地通知將被iOS忽略。

    遠程通知(須要服務器)。

    流程大概是這樣的

  • 1.生成CertificateSigningRequest.certSigningRequest文件

  • 2.將CertificateSigningRequest.certSigningRequest上傳進developer,導出.cer文件

  • 3.利用CSR導出P12文件

  • 4.須要準備下設備token值(無空格)

  • 5.使用OpenSSL合成服務器所使用的推送證書

通常使用極光推送,步驟是同樣的,只是咱們使用的服務器是極光的,不須要本身大服務器!

二十二:第三方庫&第三方平臺

  • 第三方庫:通常是指大牛封裝好的一個框架(庫),或者第三方給咱們提供的一個庫,這裏比較籠統 *第三方平臺:指第三方提供的一些服務,其實不少方面跟第三方庫是同樣的,可是仍是存在一些區別。
    區別:

  • 庫:AFN,ASI,Alomofire,MJRefresh,MJExtension,MBProgressHUD

  • 平臺:極光,百度,友盟,Mob,環信

二十三:KVO&KVC

底層實現:

  • KVC運用了一個isa-swizzling技術。isa-swizzling就是類型混合指針機制。KVC主要經過isa- swizzling,來實現其內部查找定位的。isa指針,如其名稱所指,(就是is a kind of的意思),指向維護分發表的對象的類。該分發表實際上包含了指向實現類中的方法的指針,和其它數據。

  • 當觀察者爲一個對象的屬性進行了註冊,被觀察對象的isa指針被修改的時候,isa指針就會指向一箇中間類,而不是真實的類。因此isa指 針其實不須要指向實例對象真實的類。因此咱們的程序最好不要依賴於isa指針。在調用類的方法的時候,最好要明確對象實例的類名。

    KVO概述

    KVO,即:Key-Value Observing,它提供一種機制,當指定的對象的屬性被修改後,則對象就會接受到通知。簡單的說就是每次指定的被觀察的對象的屬性被修改後,KVO就會自動通知相應的觀察者了。

    使用方法

    系統框架已經支持KVO,因此程序員在使用的時候很是簡單。

1: 註冊,指定被觀察者的屬性,

2: 實現回調方法

3: 移除觀察

KVC概述

KVC是KeyValueCoding的簡稱,它是一種能夠直接經過字符串的名字(key)來訪問類屬性(實例變量)的機制。而不是經過調用Setter、Getter方法訪問。

當使用KVO、Core Data、CocoaBindings、AppleScript(Mac支持)時,KVC是關鍵技術。

使用方法

關鍵方法定義在:NSKeyValueCodingprotocol

KVC支持類對象和內建基本數據類型。

  • 獲取值

    • valueForKey:,傳入NSString屬性的名字。

    • valueForKeyPath:,傳入NSString屬性的路徑,xx.xx形式。

    • valueForUndefinedKey它的默認實現是拋出異常,能夠重寫這個函數作錯誤處理。

  • 修改值

    • setValue:forKey:

    • setValue:forKeyPath:

    • setValue:forUndefinedKey:

    • setNilValueForKey:當對非類對象屬性設置nil時,調用,默認拋出異 常。

  • 一對多關係成員的狀況

    • mutableArrayValueForKey:有序一對多關係成員 NSArray

    • mutableSetValueForKey:無序一對多關係成員 NSSet

    補充:KVO與Notification之間的區別:

  • notification是須要一個發送notification的對象,通常是notificationCenter,來通知觀察者。

  • KVO是直接通知到觀察對象,而且邏輯很是清晰,實現步驟簡單。

二十四:時間傳遞&響應者鏈

事件的產生和傳遞過程:

  • 1.發生觸摸事件後,系統會將該事件加入到一個由UIApplication管理的隊列事件中

  • 2.UIApplication會從事件隊列中取出最前面的事件,並將事件分發下去以便處理,一般會先發送事件給應用程序的主窗口(keyWindow)

  • 3.主窗口會在視圖層次結構中找到一個最合適的視圖來處理觸摸事件

  • 4.找到合適的視圖控件後,就會調用視圖控件的touches方法來做事件的具體處理:touchesBegin… touchesMoved…touchesEnded等

  • 5.這些touches方法默認的作法是將事件順着響應者鏈條向上傳遞,將事件叫個上一個相應者進行處理

通常事件的傳遞是從父控件傳遞到子控件的

若是父控件接受不到觸摸事件,那麼子控件就不可能接收到觸摸事件 UIView不能接收觸摸事件的三種狀況:

  • 1.不接受用戶交互:userInteractionEnabled = NO;

  • 2.隱藏:hidden = YES;

  • 3.透明:alpha = 0.0~0.01

    用戶的觸摸事件首先會由系統截獲,進行包裝處理等。
      而後遞歸遍歷全部的view,進行碰觸測試(hitTest),直到找到能夠處理事件的view。
      - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event; // recursively calls -pointInside:withEvent:. point is in the receiver's coordinate system - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event; // default returns YES if point is in bounds 大體的過程application –> window –> root view –>……–>lowest view

    響應者鏈

    響應者鏈條其實就是不少響應者對象(繼承自UIResponder的對象)一塊兒組合起來的鏈條稱之爲響應者鏈條

    通常默認作法是控件將事件順着響應者鏈條向上傳遞,將事件交給上一個響應者進行處理。那麼如何判斷當前響應者的上一個響應者是誰呢?有如下兩個規則:

  • 1.判斷當前是不是控制器的View,若是是控制器的View,上一個響應者就是控制器

  • 2.若是不是控制器的View,上一個響應者就是父控件

    當有view可以處理觸摸事件後,開始響應事件。 系統會調用view的如下方法:

    - (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; 能夠多對象共同響應事件。只須要在以上方法重載中調用super的方法。 大體的過程initial view –> super view –> …..–> view controller –> window –> Application 須要特別注意的一點是,傳遞鏈中時沒有controller的,由於controller自己不具備大小的概念。可是響應鏈中是有controller的,由於controller繼承自UIResponder。

UIApplication–>UIWindow–>遞歸找到最合適處理的控件–>控件調用touches方法–>判斷是 否實現touches方法–>沒有實現默認會將事件傳遞給上一個響應者–>找到上一個響應者–>找不到方法做廢

PS:利用響應者鏈條咱們能夠經過調用touches的super 方法,讓多個響應者同時響應該事件。

二十五:堆&棧

1、堆棧空間分配區別:

* 一、棧(操做系統):由操做系統自動分配釋放 ,存放函數的參數值,局部變量的值等。其操做方式相似於數據結構中的棧; * 二、堆(操做系統): 通常由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回收,分配方式卻是相似於鏈表。

2、堆棧緩存方式區別:

* 一、棧使用的是一級緩存, 他們一般都是被調用時處於存儲空間中,調用完畢當即釋放; * 二、堆是存放在二級緩存中,生命週期由虛擬機的垃圾回收算法來決定(並非一旦成爲孤兒對象就能被回收)。因此調用這些對象的速度要相對來得低一些。

3、堆棧數據結構區別:

* 堆(數據結構):堆能夠被當作是一棵樹,如:堆排序; * 棧(數據結構):一種先進後出的數據結構。

內存其餘補充:

  • 全局區(靜態區)(static)—,全局變量和靜態變量的存儲是放在一塊的,初始化的全局變量和靜態變量在一塊區域, 未初始化的全局變量和未初始化的靜態變量在相鄰的另外一塊區域。 - 程序結束後有系統釋放
  • 文字常量區—常量字符串就是放在這裏的。 程序結束後由系統釋放
  • 程序代碼區—存放函數體的二進制代碼。

二十六:UDID&UUID

  • UDID是Unique Device Identifier的縮寫,中文意思是設備惟一標識.

    在不少須要限制一臺設備一個帳號的應用中常常會用到,在Symbian時代,咱們是使用IMEI做爲設備的惟一標識的,惋惜的是Apple官方不容許開發者得到設備的IMEI.

    [UIDevice currentDevice] uniqueIdentifier]

    可是咱們須要注意的一點是,對於已越獄了的設備,UDID並非惟一的.使用Cydia插件UDIDFaker,能夠爲每個應用分配不一樣的UDID. 因此UDID做爲標識惟一設備的用途已經不大了.

  • UUID是Universally Unique Identifier的縮寫,中文意思是通用惟一識別碼.

    由網上資料顯示,UUID是一個軟件建構的標準,也是被開源軟件基金會(Open Software Foundation,OSF)的組織在分佈式計算環境(Distributed Computing Environment,DCE)領域的一部份.UUID的目的,是讓分佈式系統中的全部元素,都能有惟一的辨識資訊,而不須要透過中央控制端來作辨識資 訊的指定.

二十七:CPU&GPU

  • CPU:中央處理器(英文Central Processing Unit)是一臺計算機的運算核心和控制核心。CPU、內部存儲器和輸入/輸出設備是電子計算機三大核心部件。其功能主要是解釋計算機指令以及處理計算機軟件中的數據。

  • GPU:英文全稱Graphic Processing Unit,中文翻譯爲「圖形處理器」。一個專門的圖形核心處理器。GPU是顯示卡的「大腦」,決定了該顯卡的檔次和大部分性能,同時也是2D顯示卡和3D 顯示卡的區別依據。2D顯示芯片在處理3D圖像和特效時主要依賴CPU的處理能力,稱爲「軟加速」。3D顯示芯片是將三維圖像和特效處理功能集中在顯示芯 片內,也即所謂的「硬件加速」功能。

二十八:點(pt)&像素(px)

  • 像素(pixels)是數碼顯示上最小的計算單位。在同一個屏幕尺寸,更高的PPI(每英寸的像素數目),就能顯示更多的像素,同時渲染的內容也會更清晰。

  • 點(points)是一個與分辨率無關的計算單位。根據屏幕的像素密度,一個點能夠包含多個像素(例如,在標準Retina顯示屏上1 pt裏有2 x 2個像素)。

當你爲多種顯示設備設計時,你應該以「點」爲單位做參考,但設計仍是以像素爲單位設計的。這意味着仍然須要以3種不一樣的分辨率導出你的素材,無論你以哪一種分辨率設計你的應用。

二十九:屬性與成員變量:

成員變量是不與外界接觸的變量,應用於類的內部,若是你說那用@Public外部不就是能夠訪問了麼。簡單的說public只能適當使用,不要氾濫,不然就像你把鑰匙插在你本身家門上了。誰來均可以開門。毫無安全性。

因爲成員變量的私有性,爲了解決外部訪問的問題就有了屬性變量。屬性變量我的認爲最大的好處就是讓其餘對象訪問這個變量。並且你能夠設置只讀、可寫等等屬性,同時設置的方法咱們也能夠本身定義。記住一點,屬性變量主要是用於與其餘對象相互交互的變量。

若是對於上面所說仍是含糊不清那就記住這幾點吧!

  • 1.只有類內使用,屬性爲private,那麼就定義成員變量。
  • 2.若是你發現你須要的這個屬性須要是public的,那麼絕不猶豫就用屬性在.h中定義。
  • 3.當你本身內部須要setter實現一些功能的時候,用屬性在.m中定義。
  • 4.當你本身內部須要getter實現一些功能的時候,用屬性在.m中定義。

    .........

待續。。。。。。。。。。

相關文章
相關標籤/搜索