每個Objective-C對象都有一個隱藏的數據結構,這個數據結構是Objective-C對象的第一個成員變量,它就是isa指針 ,這個指針是指向對象的真實類型,根據這個指針就能知道將來調用哪個類的方法
每個實例對象都有個isa指針, 他指向對象的類,而類對象里也有個isa指針, 指向meteClass(元類)。元類保存了類方法的方法列表。當類方法被調用時,先會從本身查找類方法的實現,如果沒有,元類會向他父類查找該方法。同時注意的是:元類(meteClass)也是類,它也是對象。元類也有isa指針, 它的isa指針最終指向的是一個根元類(root meteClass),其實就是NSObject. 根元類的isa指針指向本身,這樣形成了一個封閉的內循環。
判斷系統版本,UI可能會有差異 iOS7的狀態欄是懸浮在內容區域上的,即新建一個UIViewController,它的view的frame的origin.y是從屏幕頂端開始算的,而不是從狀態欄底部開始的(上移了20個像素)。
static inline 可以取代宏, 引入內聯函數是為了解決函數調用效率的問題(減少了對調用方法進棧出棧時間的開銷)
入口 setImageWithURL:placeholderImage:options: 會先 placeholderImage 顯 示,然后 SDWebImageManager 根據 URL 開始處理圖片。進入 SDWebImageManager-downloadWithURL:delegate:options:userInfo: , 交 給 SDImageCache 從緩存查找圖片是否已經下載 queryDiskCacheForKey:delegate:userInfo:.先從內存圖片緩存查找是否有圖片, 如果內存中已經有圖片緩存,SDImageCacheDelegate 回調 imageCache:didFindImage:forKey:userInfo: 到 SDWebImageManager 。 SDWebImageManagerDelegate 回調 webImageManager:didFinishWithImage: 到 UIImageView+WebCache 等前端展示圖片。如果內存緩存中沒有,生成 NSInvocationOperation 添加到隊列開始從硬盤查找圖片是否已經緩存。根據 URLKey 在硬盤緩存目錄下嘗試讀取圖片文件。這一步是在 NSOperation 進行的操 作,所以回主線程進行結果回調 notifyDelegate:。如果上一操作從硬盤讀取到了 圖片,將圖片添加到內存緩存中(如果空閑內存過小,會先清空內存緩存)。 SDImageCacheDelegate 回調 imageCache:didFindImage:forKey:userInfo:。進而 回調展示圖片。如果從硬盤緩存目錄讀取不到圖片,說明所有緩存都不存在該圖片, 需要下載圖片,回調 imageCache:didNotFindImageForKey:userInfo:。共享或重新 生成一個下載器 SDWebImageDownloader 開始下載圖片。圖片下載由 NSURLConnection 來做,實現相關 delegate 來判斷圖片下載中、下載完成和下載 失敗。connection:didReceiveData: 中利用 ImageIO 做了按圖片下載進度加載效 果。connectionDidFinishLoading: 數據下載完成后交給SDWebImageDecoder 做圖 片解碼處理。圖片解碼處理在一個 NSOperationQueue 完成,不會拖慢主線程 UI。 如果有需要對下載的圖片進行二次處理,最好也在這里完成,效率會好很多。
@PRoperty 有兩個對應的詞,一個是@synthesize,一個是@dynamic。如果 @synthesize 和@dynamic 都沒寫,那么默認的就是@syntheszie var = _var; @synthesize 的語義是如果你沒有手動實現 setter 方法和 getter 方法,那么編譯器 會自動為你加上這兩個方法 @dynamic 告訴編譯器:屬性的 setter 與 getter 方法由用戶自己實現,不自動生 成(當然對于 readonly 的屬性只需提供 getter 即可) 假如一個屬性被聲明為@dynamic var,然后你沒有提供@setter 方法和@getter 方 法,編譯的時候沒問題,但是當程序運行到 instance.var = someVar,由于缺 setter 方法會導致程序崩潰;或者當運行到 someVar = instance.var 時,由于缺 getter 方 法同樣會導致崩潰。編譯時沒問題,運行時才執行相應的方法,這就是所 謂的動態綁定
KVO 是基于 runtime 機制實現的 當某個類的屬性對象第一次被觀察時,系統就會在運行期動態地創建該類的一 個派生類,在這個派生類中重寫基類中任何被觀察屬性的 setter 方法。派生類在 被重寫的 setter 方法內實現真正的通知機制 如果原類為 Person,那么生成的派生類名為 NSKVONotifying_Person 每個類對象中都有一個 isa 指針指向當前類,當一個類對象的第一次被觀察,那么 系統會偷偷將 isa 指針指向動態生成的派生類,從而在給被監控屬性賦值時執行的 是派生類的 setter 方法 鍵值觀察通知依賴于 NSObject 的兩個方法 : willChangeValueForKey: 和 didChangevlueForKey:;在一個被觀察屬性發生改變之前, willChangeValueForKey: 一定會被調用,這就 會記錄舊的值。而當改變發生后,didChangeValueForKey: 會 被調用,繼而 observeValueForKey:ofObject:change:context: 也會被調用。 補充:KVO 的這套實現機制中蘋果還偷偷重寫了 class 方法,讓我們誤認為還是使 用的當前類,從而達到隱藏生成的派生類
App生命周期: 剛啟動時: application:didFinishLaunchingWithOptions: applicationDidBecomeActive: 進入后臺時 applicationWillResignActive: applicationDidEnterBackground: 進入前臺時 applicationWillEnterForeground: applicationDidBecomeActive: ViewController生命周期: 剛啟動時: init / awakeFromNib(ViewController是從Xib加載的就會調用該方法) loadView viewDidLoad viewWillAppear: viewDidAppear: 跳轉到第二個頁面: [SecondViewController init] [FirstViewController viewWillDisappear:] [SecondViewController loadView] [SecondViewController viewDidLoad] [SecondViewController viewWillAppear:] [FirstViewController viewDidDisappear:] [SecondViewController viewDidAppear:]
從第二個頁面回到第一個頁面: [SecondViewController viewWillDisappear:] [FirstViewController viewWillAppear:] [SecondViewController viewDidDisappear:] [FirstViewController viewDidAppear:]
iOS遠程推送的前提是:裝有我們應用程序的iOS設備,需要向APNs服務器注冊,注冊成功后,APNs服務器將會給我們返回一個devicetoken,我們獲取到這個token后會將這個token發送給我們自己的應用服務器。當我們需要推送消息時,我們的應用服務器將消息按照指定的格式進行打包,然后結合iOS設備的 devicetoken一起發給APNs服務器。我們的應用會和APNs服務器維持一個基于TCP的長連接,APNs服務器將新消息推送到iOS設備上,然后在設備屏幕上顯示出推送的消息。
詳細步驟如下: 1.A用戶發送手機設備的UDID和應用的Bundle ID給APNs服務器注冊 2.APNs根據設備的UDID和應用的Bundle ID生成一個deviceToken返回給A 3.發送A用戶的deviceToken和用戶的標識(比如微信號)給應用的服務器 4.應用服務器保存進數據庫 5.B用戶給A用戶發送了一套消息,先發送到應用的服務器,應用服務器根據唯一標識找到A的deviceToken 6.應用服務器把A的deviceToken和B發送的信息一起發送給APNs服務器 7.APNs服務器再根據deviceToken找到A用戶,再把信息推送到A的手機設備,已通知的形式展示推送的信息
OC 語言是 C 語言的一個超集, 只是在 C 的基礎之上加上了面向對象 (oop) 的特性; OC 與 java 語言相同都是單繼承, 這一點與 C++ 語言不同(多重繼承); OC 不支持命名空間機制, 取而代之的是在類名之前添加前綴, 以此來區分。
OC作為一門面向對象的語言,自然具有面向對象的語言特性,如:封裝、多態、繼承。它具有靜態語言的特性,又有動態語言的效率。 Objective-C 具有相當多的動態特性,表現在三個方面:動態類型、動態綁定、動態加載。之所以叫做動態,是因為必須到運行時才會做一些事情。 1、 動態類型 :即運行時再決定對象的真實類型。這類動態類型在日常應用中非常常見。簡單說就是id類型。實際上靜態類型因為其固定性和可預知性而使用的非常廣泛,靜態類型是強類型,而動態類型屬于弱類型。運行時決定接受者。 2、 動態綁定 :基于動態類型,在某個實例對象被確定后,其類型就被確定了。該對象的屬性和響應的消息也被完全確定,這就是動態綁定。 3、 動態加載 :根據需求加載所需要的資源,這點很容易理解,對于iOS開發來說,基本就是根據不同的機型做適配。最經典的例子就是在Retina 設備上加載@2x的圖片,而在老一些的普通設備上加載原圖。隨著Retina ipad的推出,和之后可能的Retina Mac的出現,這個特性相信會被越來越多的使用。讓程序在運行時添加代碼塊以及其他資源。用戶可以根據需要加載一些可執行代碼和資源,而不是在啟動時就加載所有組件??蓤绦写a中可以含有和程序運行時整合的新類。
在每一個事件周期(event cycle)的開始,系統會自動創建一個自動釋放池;在每一個事件周期的結尾,系統會自動銷毀這個自動釋放池。一般情況下,你可以理解為:當你的代碼在持續運行時,自動釋放池是不會被銷毀的,這段時間內你也可以安全地使用自動釋放的對象;當你的代碼運行告一段落,開始等待用戶輸入(或者其它事件)時,自動釋放池就會被釋放掉,池中的對象都會收到一條release消息,當對象的引用計數器為0時會被銷毀。 自動釋放而非直接釋放,可以幫助你節省一些代碼量,提高開發速度。但是它有一個直接的缺點:它延緩了對象的釋放,在有大量自動釋放的對象時,會占用大量內存資源。因此,你需要避免將大量對象自動釋放。并且,在以下兩種情況下,你需要手動建立并手動銷毀掉自動釋放池: 1.當你在主線程外開啟其它線程時:系統只會在主線程中自動生成并銷毀掉自動釋放池。 2.當你在短時間內制造了大量自動釋放對象時:及時地銷毀有助于有效利用設備上有限地內存資源。
新聞熱點
疑難解答