[TOC]html
1. 首先搞清楚什麼是線程、什麼是多線程 2. Mach是第一個以多線程方式處理任務的系統,所以多線程的底層實現機制是基於Mach的線程 3. 開發中不多用Mach級的線程,由於Mach級的線程沒有提供多線程的基本特徵,線程之間是獨立的 4. 開發中實現多線程的方案 C語言的POSIX接口:#include <pthread.h> OC的NSThread C語言的GCD接口(性能最好,代碼更精簡) OC的NSOperation和NSOperationQueue(基於GCD)
1. performSelector:onThread:withObject:waitUntilDone: 2. NSMachPort
利用字典(圖片地址爲key,下載操做爲value),具體能夠查看SD緩存機制
NSOperationQueue *queue = [[NSOperationQueue alloc] init]; NSOperation *A = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"SuperLog------ NSOperationA"); }]; NSOperation *B = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"SuperLog------ NSOperationB"); }]; NSOperation *C = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"SuperLog------ NSOperationC"); }]; [C addDependency:A]; [C addDependency:B]; [queue addOperation:A]; [queue addOperation:B]; [queue addOperation:C];
1. 只在主線程刷新訪問UI 2. 若是要防止資源搶奪,得用synchronized進行加鎖保護 3. 若是異步操做要保證線程安全等問題, 儘可能使用GCD(有些函數默認就是安全的)
1. iOS和OS X的核心是XNU內核,GCD是基於XNU內核實現的 2. GCD的API所有在libdispatch庫中 3. GCD的底層實現主要有Dispatch Queue和Dispatch Source Dispatch Queue :管理block(操做) Dispatch Source :處理事件
1. GCD是純C語言的API,NSOperationQueue是基於GCD的OC版本封裝 2. GCD只支持FIFO的隊列,NSOperationQueue能夠很方便地調整執行順序、設置最大併發數量 3. NSOperationQueue能夠在輕鬆在Operation間設置依賴關係,而GCD須要寫不少的代碼才能實現 4. NSOperationQueue支持KVO,能夠監測operation是否正在執行(isExecuted)、是否結束(isFinished),是否取消(isCanceld) 5. GCD的執行速度比NSOperationQueue快 任務之間不太互相依賴:GCD 任務之間有依賴\或者要監放任務的執行狀況:NSOperationQueue
Block的使用注意: 1. block的內存管理 2. 防止循環retian 非ARC(MRC):__block ARC:__weak\__unsafe_unretained
1. 從新下載圖片 2. 下載完畢, 利用RunLoop的輸入源回到主線程刷新UIImageView
1. 使用Analyze進行代碼的靜態分析 2. 儘可能使用ARC
建立單例設計模式的基本步驟: 1. 聲明一個單件對象的靜態實例,並初始化爲nil 2. 建立一個類的類工廠方法,當且僅當這個類的實例爲nil時生成一個該類的實例 3. 實現NScopying協議, 覆蓋allocWithZone:方法,確保用戶在直接分配和初始化對象時,不會產生另外一個對象 4. 覆蓋release、autorelease、retain、retainCount方法, 以此確保單例的狀態。 5. 在多線程的環境中,注意使用@synchronized關鍵字或GCD,確保靜態實例被正確的建立和初始化。
1. 系統自帶的絕大數類方法返回的對象,都是通過autorelease的
1. 對於沒有引用外部變量的Block,不管在ARC仍是非ARC下,類型都是__NSGlobalBlock__,這種類型的block能夠理解成一種全局的block,不須要考慮做用域問題。同時,對他進行Copy或者Retain操做也是無效的 2. 應注意避免循環引用
1. 當程序在申請內存後,沒法釋放已申請的內存空間(例如一個對象或者變量使用完成後沒有釋放,這個對象一直佔用着內存),一次內存泄露危害能夠忽略,但內存泄露堆積後果很嚴重,不管多少內存,早晚會被佔光。內存泄露會最終會致使內存溢出! 2. 當程序在申請內存時,沒有足夠的內存空間供其使用,出現out of memory;好比申請了一個int,但給它存了long才能存下的數,那就是內存溢出。
[NSArray arrayWithobject:(id)obj]
這個方法添加對象後,須要對這個數組作釋放操做嗎?不須要這個對象被放到自動釋放池中
自動釋放池以棧的形式實現:當你建立一個新的自動釋放池時,它將被添加到棧頂。當一個對象收到發送autorelease消息時,它被添加到當前線程的處於棧頂的自動釋放池中,當自動釋放池被回收時,它們從棧中被刪除, 而且會給池子裏面全部的對象都會作一次release操做.
1. KVO是基於runtime機制實現的 2. 當某個類的對象第一次被觀察時,系統就會在運行期動態地建立該類的一個派生類,在這個派生類中重寫基類中任何被觀察屬性的setter方法。 3. 派生類在被重寫的 setter 方法實現真正的通知機制(NSKVONotifying_Class)
若是在異步線程發的通知,那麼能夠執行比較耗時的操做 若是在主線程發的通知,那麼就不能夠執行比較耗時的操做
1. Foundation對象是OC的,Core Foundation對象是C對象 2. 數據類型之間的轉換 ARC:__bridge_retained、__bridge_transfer 非ARC: __bridge
A = A + B B = A - B A = A - B A = A^B; B = A^B; A = A^B;
節省內存資源,一個應用就一個對象。
運行時機制,runtime庫裏面包含了跟類、成員變量、方法相關的API,好比獲取類裏面的全部成員變量,爲類動態添加成員變量,動態改變類的方法實現,爲類動態添加新的方法等 須要導入<objc/message.h> <objc/runtime.h> 1. runtime,運行時機制,它是一套C語言庫 2. 實際上咱們編寫的全部OC代碼,最終都是轉成了runtime庫的東西,好比類轉成了runtime庫裏面的結構體等數據類型,方法轉成了runtime庫裏面的C語言函數,平時調方法都是轉成了objc_msgSend函數(因此說OC有個消息發送機制)。所以,能夠說runtime是OC的底層實現,是OC的幕後執行者 3. 有了runtime庫,能作什麼事情呢?runtime庫裏面包含了跟類、成員變量、方法相關的API,好比獲取類裏面的全部成員變量,爲類動態添加成員變量,動態改變類的方法實現,爲類動態添加新的方法等。所以,有了runtime,想怎麼改就怎麼改
CoreText 1. 隨意修改文本的樣式 2. 圖文混排(純C語言) 3. 國外:Niumb Core Image(濾鏡處理) - 能調節圖片的各類屬性(對比度, 色溫, 色差等)
通知比較靈活(1個通知能被多個對象接收, 1個對象能接收多個通知) 代理比較規範,可是代碼多(默認是1對1) KVO性能很差(底層會動態產生新的類),只能監聽某個對象屬性的改變, 不推薦使用(1個對象的屬性能被多個對象監聽,1個對象能監聽多個對象的其餘屬性)
更詳細參考:java
原文ios
翻譯web
Objective-C是對C語言的擴展,block的實現是基於指針和函數指針
算法題,百度本身學習。 思路 1. 計算 differ = sum(a) - sum(b) 2. 尋找 a b 數組中差值最接近differ/2 的元素 3. 交換元素
編寫SQL語句來操做原來表中的字段 1. 增長表字段 ALTER TABLE 表名 ADD COLUMN 字段名 字段類型; 2. 刪除表字段 ALTER TABLE 表名 DROP COLUMN 字段名; 3. 修改表字段 ALTER TABLE 表名 RENAME COLUMN 舊字段名 TO 新字段名;
1. 添加SQLite動態庫 2. 導入主頭文件:#import <sqlite3.h> 3. 利用C語言函數建立/打開數據庫,編寫SQL語句
1. 緩存能夠分爲:內存數據緩存、數據庫緩存、文件緩存 2. 每次想獲取數據的時候 2.1 先檢測內存中有無緩存 2.2 再檢測本地有無緩存(數據庫\文件) 2.3 最終發送網絡請求 2.4 將服務器返回的網絡數據進行緩存(內存、數據庫、文件),以便下次讀取
1. CoreData是對SQLite數據庫的封裝 2. CoreData中的NSManagedObjectContext在多線程中不安全 3. 若是想要多線程訪問CoreData的話,最好的方法是一個線程一個NSManagedObjectContext 4. 每一個NSManagedObjectContext對象實例均可以使用同一個NSPersistentStoreCoordinator實例,這是由於NSManagedObjectContext會在便用NSPersistentStoreCoordinator前上鎖
ios中不存在緩存池滿的狀況,由於一般咱們ios中開發,對象都是在須要的時候纔會建立,有種經常使用的說話叫作懶加載,還有在UITableView中通常只會建立剛開始出如今屏幕中的cell,以後都是從緩存池裏取,不會在建立新對象。緩存池裏最多也就一兩個對象,緩存池滿的這種狀況通常在開發java中比較常見,java中通常把最近最少使用的對象先釋放。
Core Animation Programming Guideobjective-c
// cnblog mermaid 使用後,[TOC] 目錄失效,因此暫時放上源碼和一張截圖。 graph TB A(CAAnimation) --> B1(CAPropertyAnimation) A --> B2(CAAnimationGroup) A --> B3(CATransition) B1 --> C1(CABasicAnimation) B1 --> C2(CAKeyframeAnimation) C1 --> D(CASpringAnimation)
如何找到最合適的視圖 1. 本身是否能接收觸摸事件 2. 觸摸點是否在本身身上 3. 從後往前遍歷子控件,重複前面的兩個步驟 4. 若是沒有符合條件的子控件,那麼本身最適合處理
1. 首先判斷控制器是否有視圖,若是沒有就調用loadView方法建立(storyboard/代碼) 2. 隨後調用viewDidLoad,能夠進行下一步的初始化操做(只會被調用一次) 3. 在視圖顯示以前調用viewWillAppear(該函數能夠屢次調用) 4. viewDidAppear 3. 在視圖顯示以前調用viewWillDisappear;該函數能夠屢次調用(如須要) 5. 在佈局變化先後,調用viewWill/DidLayoutSubviews處理相關信息
NSRunLoop是iOS消息機制的處理模式 1. NSRunLoop的主要做用:控制NSRunLoop裏面線程的執行和休眠,在有事情作的時候使當前NSRunLoop控制的線程工做,沒有事情作讓當前NSRunLoop的控制的線程休眠。 2. NSRunLoop 就是一直在循環檢測,從線程start到線程end,檢測inputsource(如點擊,雙擊等操做)異步事件,檢測timesource同步事件,檢測到輸入源會執行處理函數,首先會產生通知,corefunction向線程添加runloop observers來監聽事件,意在監聽事件發生時來作處理。 3. runloopmode是一個集合,包括監聽:事件源,定時器,以及需通知的runloop observers 多線程中如何使用? 1. 只有在爲你的程序建立次線程的時候,才須要運行run loop。對於程序的主線程而言,run loop是關鍵部分。Cocoa提供了運行主線程run loop的代碼同時也會自動運行run loop。iOS程序UIApplication中的run方法在程序正常啓動的時候就會啓動run loop。若是你使用xcode提供的模板建立的程序,那你永遠不須要本身去啓動run loop 2. 在多線程中,你須要判斷是否須要run loop。若是須要run loop,那麼你要負責配置run loop並啓動。你不須要在任何狀況下都去啓動run loop。好比,你使用線程去處理一個預先定義好的耗時極長的任務時,你就能夠毋需啓動run loop。Run loop只在你要和線程有交互時才須要
通常的應用在進入後臺的時候能夠獲取必定時間來運行相關任務,也就是說能夠在後臺運行一小段時間(10S左右)。 1. 後臺播放音樂 2. 後臺GPS跟蹤 3. 後臺voip支持
程序啓動分爲兩類: 1. 有storyboard 2. 沒有storyboard 狀況一: 1.main函數 2.UIApplicationMain * 建立UIApplication對象 * 建立UIApplication的delegate對象 3.根據Info.plist得到最主要storyboard的文件名,加載最主要的storyboard(有storyboard) * 建立UIWindow * 建立和設置UIWindow的rootViewController * 顯示窗口 狀況二: 1.main函數 2.UIApplicationMain * 建立UIApplication對象 * 建立UIApplication的delegate對象 3.delegate對象開始處理(監聽)系統事件(沒有storyboard) * 程序啓動完畢的時候, 就會調用代理的application:didFinishLaunchingWithOptions:方法 * 在application:didFinishLaunchingWithOptions:中建立UIWindow * 建立和設置UIWindow的rootViewController * 顯示窗口
1. 關掉後不執行任何代碼,不能處理事件 2. 應用程序進入後臺狀態不久後轉入掛起狀態。在這種狀態下,應用程序不執行任何代碼,並有可能在任意時候從內存中刪除。只有當用戶再次運行此應用,應用纔會從掛起狀態喚醒,代碼得以繼續執行 3. 或者進入後臺時開啓多任務狀態,保留在內存中,這樣就能夠執行系統容許的動做 4. 遠程推送是由遠程服務器上的程序發送到APNS,再由APNS把消息推送至設備上的程序,當應用程序收到推送的消息會自動調用特定的方法執行事先寫好的代碼 5. 本地通知和遠程推送通知對基本概念和用法? * 本地通知和遠程推送通知均可以向不在前臺運行的應用發送消息,這種消息既多是即將發生的事件,也多是服務器的新數據.不論是本地通知仍是遠程通知,他們在程序界面的顯示效果相同,均可能顯示爲一段警告信息或應用程序圖標上的微章. * 本地通知和遠程推送通知的基本目的都是讓應用程序可以通知用戶某些事情,並且不須要應用程序在前臺運行.兩者的區別在於本地通知由本應用負責調用,只能從當前設備上的iOS發出, 而遠程通知由遠程服務器上的程序發送到APNS,再由APNS把消息推送至設備上的程序
1. SIP(Session Initiation Protocol),會話發起協議 2. SIP是創建VOIP鏈接的 IETF 標準,IETF是全球互聯網最具權威的技術標準化組織 3. 所謂VOIP,就是網絡電話,直接用互聯網打電話,不用耗手機話費
1. 圖片下載放在異步線程 2. 圖片下載過程當中使用佔位圖片 3. 若是圖片較大,能夠考慮多線程斷點下載
1. 提供給外界的接口功能是否實用、夠用 2. 能不能根據類名、方法名就猜出接口的具體做用 3. 提供的參數是否夠用、調用起來是否簡單 4. 要不要再導入依賴其餘的框架
1. 設置請求超時 2. 給用戶提示請求超時 3. 根據用戶操做再次請求數據
1. 若是通知是在主線程發出,那麼接收通知的方法中的耗時操做要放到異步線程中 2. 若是通知實在異步線程中發出,那麼接收通知後調用的方法會默認在異步線程中執行
1. 利用NSOperationQueue和NSOperation下載圖片, 還使用了GCD的一些函數(解碼GIF圖片) 2. 利用URL做爲key,NSOperation做爲value 3. 利用URL做爲key,UIImage做爲value 待完善...
1. AFN基於NSURL,ASI基於底層的CFNetwork框架,所以ASI的性能優於AFN 2. AFN採起block的方式處理請求,ASI最初採起delegate的方式處理請求,後面也增長了block的方式 3. AFN只封裝了一些經常使用功能,知足基本需求,直接忽略了不少擴展功能,好比沒有封裝同步請求;ASI提供的功能較多,預留了各類接口和工具供開發者自行擴展 4. AFN直接解析服務器返回的JSON、XML等數據,而ASI比較原始,返回的是NSData二進制數據
1. 你建立的程序不須要顯示的建立run loop;每一個線程,包括程序的主線程(main thread)都有與之相應的run loop對象, 主線程會自行建立並運行run loop 2. Runloop處理的輸入事件有兩種不一樣的來源:輸入源(input source)和定時源(timer source) 3. 輸入源傳遞異步消息,一般來自於其餘線程或者程序。定時源則傳遞同步消息,在特定時間或者必定的時間間隔發生
1. 檢查網絡請求操做是否被放在主線程了 2. 看看異步請求的數量是否太多了(子線程數量) 3. 數據量是否太大?若是太大,先清除一些沒必要要的對象(看不見的數據、圖片) 4. 手機CPU使用率和內存問題
1. 設置數據庫鎖定的處理函數 int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); 2. 設定鎖定時的等待時間 int sqlite3_busy_timeout(sqlite3*, 60);