後續我也會一直講本文更新下去,有遺漏點或者錯誤的地方望指出,或者聯繫我,相互交流技術,謝謝!ios
好了開始吧。。。。。。。。。。。git
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
類別主要有三個做用數據庫
(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,這樣類的結構更加清晰。
2: 經過@dynamic指令,本身實現方法。
有些存取是在運行時動態建立的,如在CoreData的NSManagedObject類使用的某些。若是你想這些狀況下,聲明和使用屬性,但要避免缺乏方法在編譯時的警告,你能夠使用@dynamic動態指令,而不是@synthesize合成指令。
一、在Mac OS中NSWindow的父類是NSResponder,而在i OS 中UIWindow 的父類是UIVIew。程序通常只有一個窗口可是會又不少視圖。
二、UIView的做用:描畫和動畫,視圖負責對其所屬的矩形區域描畫、佈局和子視圖管理、事件處理、能夠接收觸摸事件、事件信息的載體、等等。
三、UIViewController 負責建立其管理的視圖及在低內存的時候將他們從內存中移除。還爲標準的系統行爲進行響應。
四、layOutSubViews 能夠在本身定製的視圖中重載這個方法,用來調整子視圖的尺寸和位置。
五、UIView的setNeedsDisplay和setNeedsLayout方法。首先兩個方法都是異步執行的。而 setNeedsDisplay會調用自動調用drawRect方法,這樣能夠拿到UIGraphicsGetCurrentContext,就能夠畫畫 了。而setNeedsLayout會默認調用layoutSubViews,就能夠處理子視圖中的一些數據。
綜上所述:setNeedsDisplay方便繪圖,而layoutSubViews方便出來數據
setNeedDisplay告知視圖它發生了改變,須要從新繪製自身,就至關於刷新界面.
UIView是iOS系統中界面元素的基礎,全部的界面元素都繼承自它。它自己徹底是由CoreAnimation來實現的(Mac下彷佛不是這 樣)。它真正的繪圖部分,是由一個叫CALayer(Core Animation Layer)的類來管理。UIView自己,更像是一個CALayer的管理器,訪問它的跟繪圖和跟座標有關的屬性,例如frame,bounds等等, 實際上內部都是在訪問它所包含的CALayer的相關屬性。
UIView有個重要屬性layer,能夠返回它的主CALayer實例。
UIView的CALayer相似UIView的子View樹形結構,也能夠向它的layer上添加子layer,來完成某些特殊的表示。即CALayer層是能夠嵌套的。
UIView的layer樹形在系統內部,被維護着三份copy。分別是邏輯樹,這裏是代碼能夠操縱的;動畫樹,是一箇中間層,系統就在這一層上更改屬性,進行各類渲染操做;顯示樹,其內容就是當前正被顯示在屏幕上得內容。
動畫的運做:對UIView的subLayer(非主Layer)屬性進行更改,系統將自動進行動畫生成,動畫持續時間的缺省值彷佛是0.5秒。
座標系統:CALayer的座標系統比UIView多了一個anchorPoint屬性,使用CGPoint結構表示,值域是0~1,是個比例值。
渲染:當更新層,改變不能當即顯示在屏幕上。當全部的層都準備好時,能夠調用setNeedsDisplay方法來重繪顯示。
變換:要在一個層中添加一個3D或仿射變換,能夠分別設置層的transform或affineTransform屬性。
變形:Quartz Core的渲染能力,使二維圖像能夠被自由操縱,就好像是三維的。圖像能夠在一個三維座標系中以任意角度被旋轉,縮放和傾斜。CATransform3D的一套方法提供了一些魔術般的變換效果。
UICollectionView是iOS6新引進的API,用於展現集合視圖,佈局更加靈活,其用法相似於UITableView。而 UICollectionView、UICollectionViewCell與UITableView、UITableViewCell在用法上有類似 的也有不一樣的,下面是一些基本的使用方法:
對於UITableView,僅須要UITableViewDataSource,UITableViewDelegate這兩個協議,使用 UICollectionView須要實現UICollectionViewDataSource, UICollectionViewDelegate,UICollectionViewDelegateFlowLayout這三個協議,這是由於 UICollectionViewDelegateFlowLayout其實是UICollectionViewDelegate的一個子協議,它繼承 了UICollectionViewDelegate,它的做用是提供一些定義UICollectionView佈局模式的函數
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在如下狀況下會被調用:
drawRect在如下狀況下會被調用:
drawRect方法使用注意點:
一、 若使用UIView繪圖,只能在drawRect:方法中獲取相應的contextRef並繪圖。若是在其餘方法中獲取將獲取到一個invalidate 的ref而且不能用於畫圖。drawRect:方法不能手動顯示調用,必須經過調用setNeedsDisplay 或 者 setNeedsDisplayInRect,讓系統自動調該方法。
二、若使用calayer繪圖,只能在drawInContext: 中(相似魚drawRect)繪製,或者在delegate中的相應方法繪製。一樣也是調用setNeedDisplay等間接調用以上方法 三、若要實時畫圖,不能使用gestureRecognizer,只能使用touchbegan等方法來掉用setNeedsDisplay實時刷新屏幕
NSCache與可變集合有幾點不一樣:
NSCache和NSDictionary相似,不一樣的是系統回收內存的時候它會自動刪掉它的內容。
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),隊列的大小能夠自動調整
能夠看到這兩個方法都是以「+」開頭的類方法,返回爲空。一般狀況下,咱們在開發過程當中可能沒必要關注這兩個方法。若是有須要定製,咱們能夠在自定義的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也不會被調用。
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裏,View是能夠直接訪問Model的!從而,View裏會包含Model信息,不可避免的還要包括一些業務邏輯。 MVC模型關注的是Model的不變,因此,在MVC模型裏,Model不依賴於View,可是 View是依賴於Model的。不只如此,由於有一些業務邏輯在View裏實現了,致使要更改View也是比較困難的,至少那些業務邏輯是沒法重用的。
MVVM在概念上是真正將頁面與數據邏輯分離的模式,它把數據綁定工做放到一個JS裏去實現,而這個JS文件的主要功能是完成數據的綁定,即把model綁定到UI的元素上。
有人作過測試:使用Angular(MVVM)代替Backbone(MVC)來開發,代碼能夠減小一半。
此外,MVVM另外一個重要特性,雙向綁定。它更方便你同時維護頁面上都依賴於某個字段的N個區域,而不用手動更新它們。
總結:
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(Transmission Control Protocol,傳輸控制協議)是基於鏈接的協議,也就是說,在正式收發數據前,必須和對方創建可靠的鏈接。一個TCP鏈接必需要通過三次「對話」才能 創建起來,其中的過程很是複雜,咱們這裏只作簡單、形象的介紹,你只要作到可以理解這個過程便可。
UDP(User Data Protocol,用戶數據報協議)是與TCP相對應的協議。它是面向非鏈接的協議,它不與對方創建鏈接,而是直接就把數據包發送過去! UDP適用於一次只傳送少許數據、對可靠性要求不高的應用環境。
建議: 一、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和sqlite的概念不一樣,core爲對象週期管理,而sqlite爲dbms。
推送通知:推送到用戶手機對應的App上(主要是再也不前臺的狀況)
本地通知。
local notification,用於基於時間行爲的通知,好比有關日曆或者todo列表的小應用。另外,應用若是在後臺執行,iOS容許它在受限的時間內運 行,它也會發現本地通知有用。好比,一個應用,在後臺運行,嚮應用的服務器端獲取消息,當消息到達時,好比下載更新版本的提示消息,經過本地通知機制通知 用戶。
本地通知是UILocalNotification的實例,主要有三類屬性:
scheduled time,時間週期,用來指定iOS系統發送通知的日期和時間;
自定義數據,本地通知能夠包含一個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
底層實現:
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、堆棧數據結構區別:
* 堆(數據結構):堆能夠被當作是一棵樹,如:堆排序; * 棧(數據結構):一種先進後出的數據結構。
內存其餘補充:
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:中央處理器(英文Central Processing Unit)是一臺計算機的運算核心和控制核心。CPU、內部存儲器和輸入/輸出設備是電子計算機三大核心部件。其功能主要是解釋計算機指令以及處理計算機軟件中的數據。
GPU:英文全稱Graphic Processing Unit,中文翻譯爲「圖形處理器」。一個專門的圖形核心處理器。GPU是顯示卡的「大腦」,決定了該顯卡的檔次和大部分性能,同時也是2D顯示卡和3D 顯示卡的區別依據。2D顯示芯片在處理3D圖像和特效時主要依賴CPU的處理能力,稱爲「軟加速」。3D顯示芯片是將三維圖像和特效處理功能集中在顯示芯 片內,也即所謂的「硬件加速」功能。
像素(pixels)是數碼顯示上最小的計算單位。在同一個屏幕尺寸,更高的PPI(每英寸的像素數目),就能顯示更多的像素,同時渲染的內容也會更清晰。
點(points)是一個與分辨率無關的計算單位。根據屏幕的像素密度,一個點能夠包含多個像素(例如,在標準Retina顯示屏上1 pt裏有2 x 2個像素)。
當你爲多種顯示設備設計時,你應該以「點」爲單位做參考,但設計仍是以像素爲單位設計的。這意味着仍然須要以3種不一樣的分辨率導出你的素材,無論你以哪一種分辨率設計你的應用。
成員變量是不與外界接觸的變量,應用於類的內部,若是你說那用@Public外部不就是能夠訪問了麼。簡單的說public只能適當使用,不要氾濫,不然就像你把鑰匙插在你本身家門上了。誰來均可以開門。毫無安全性。
因爲成員變量的私有性,爲了解決外部訪問的問題就有了屬性變量。屬性變量我的認爲最大的好處就是讓其餘對象訪問這個變量。並且你能夠設置只讀、可寫等等屬性,同時設置的方法咱們也能夠本身定義。記住一點,屬性變量主要是用於與其餘對象相互交互的變量。
若是對於上面所說仍是含糊不清那就記住這幾點吧!
4.當你本身內部須要getter實現一些功能的時候,用屬性在.m中定義。
.........
待續。。。。。。。。。。