參考:
Apple Developer
Apple OpenSource
1. 基礎知識點:
Cocoa Touch
是apple基于手機觸摸的一套基礎框架,包括音頻視頻,數(shù)據(jù)管理,網(wǎng)絡,用戶應用等框架;
查看官方文檔說明
>> runtime運行時原理
runtime是一套比較底層的純C語言API,我們平時編寫的OC代碼中, 程序運行過程時, 其實最終都是轉成了runtime的C語言代碼;
利用runtime機制讓我們可以在程序運行時動態(tài)修改類、對象中的所有屬性、方法;
用處:
- 動態(tài)創(chuàng)建一個類;
- 動態(tài)為某個類添加屬性\方法,修改屬性值\方法;
- 遍歷一個類的所有成員變量(屬性)\所有方法 例如:我們需要對一個類的屬性進行歸檔解檔的時候屬性特別的多,這時候,我們就會寫很多對應的代碼,但是如果使用了runtime就可以動態(tài)設置;
相關函數(shù): - objc_msgSend : 給對象發(fā)送消息
- class_addMethod: 添加方法
- class_copyMethodList : 遍歷某個類所有的方法
- class_copyIvarList : 遍歷某個類所有的成員變量
IOS的函數(shù)調用是在運行時通過objc_msgSend決定的;
GCD (Grand Central Dispatch)
GCD的工作原理是:讓程序平行排隊的特定任務,根據(jù)可用的處理資源,安排他們在任何可用的處理器核心上執(zhí)行任務。一個任務可以是一個函數(shù)(function)或者是一個block。 GCD的底層依然是用線程實現(xiàn),不過這樣可以讓程序員不用關注實現(xiàn)的細節(jié);
常用函數(shù):
dispatch_async dispatch_group_async dispatch_barrier_async dispatch_apply
APNS (Apple Push Notification service)
APNS的消息注冊跟消息吹都在AppDelegate中處理,使用:
didRegisterForRemoteNotificationsWithDeviceToken
didReceiveRemoteNotification
相關application函數(shù);
工作原理:
- 應用注冊,由iOS系統(tǒng)向APNS請求返回設備令牌;
(void)application:(UIApplication )application didRegisterForRemoteNotificationsWithDeviceToken:(NSData)deviceToken; - 應用程序接收到設備令牌并發(fā)送給服務器;
- 服務器把要提送的內容和設備發(fā)送給APNS;
- APNS根據(jù)設備令牌找到設備,再由iOS根據(jù)APPID把推送內容展示;
NSZone
可以想象成一個內存池,alloc與dealloc這些操作,都是在這個內存池中操作的,cocoa總是會配置一個默認的NSZone,任何默認的內存操作都是在這個zone上操作的;
默認的NSZone是全局的,時間一長,必然會導致內存碎片化,如果大量的alloc一些object,那么性能就會收到影響;所以cocoa提供方法,你可以自己生成一個NSZone,并將alloc,copy全部限制在這個zone之內;
>> 數(shù)據(jù)存儲
>> 沙盒
http://www.cnblogs.com/luckhao/p/5437896.html
沙盒目錄結構
文件存儲
- plist 存儲
存放一些基本數(shù)據(jù)類型的數(shù)據(jù),一般在Document目錄下,plist路徑獲取代碼示例:
NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
NSString *fileName = [path stringByAppendingPathComponent:@"123.plist"];
- 偏好設置存儲
偏好設置是專門用來保存應用程序的配置信息的,一般不要保存其他安全性數(shù)據(jù);
如果要立即同步數(shù)據(jù)到文件,使用synchronize;
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults synchronize];
偏好設置會將所有數(shù)據(jù)保存到同一個文件中。即preference目錄下的一個以此應用包名來命名的plist文件;
- 歸檔操作 NSKeyedArchiver
歸檔在iOS中是另一種形式的序列化,只要遵循了NSCoding協(xié)議的對象都可以通過它實現(xiàn)序列化;
保存文件的擴展名可以任意指定;
數(shù)據(jù)庫存儲:
- SQLite 輕型嵌入式關系數(shù)據(jù)庫,包含在一個相對小的c庫中,基于C的API操作;
- CoreData:對象關系映射(ORM),它將數(shù)據(jù)庫的創(chuàng)建,表的創(chuàng)建,對象與表的轉換操作等封裝起來,簡化了我么的操作;開發(fā)者只要把模型搭建起來,具體數(shù)據(jù)庫如何創(chuàng)建不用管,在IOS項目中添加“Data Model”文件;
- 第三方架構FMDB: 相比于SQLite3來說Core Data存在著諸多優(yōu)勢,它面向對象,開發(fā)人員不必過多的關心更多數(shù)據(jù)庫操作知識,同時它基于ObjC操作,書寫更加優(yōu)雅等。
多線程訪問數(shù)據(jù)同步?
NSLock
常用函數(shù) lock,unlock;NSCondition
A condition object acts as both a lock and a checkpoint in a given thread. 即它表示一個鎖+一個線程檢查器,線程檢查器主要是根據(jù)條件決定是否繼續(xù)運行線程,即線程是否被阻塞;
常用函數(shù):
lock,unlock
wait:等待其他線程發(fā)出信號,此時其他線程可訪問lock區(qū)域內的內容,wait相當于在調用時候unlock了,然后觸發(fā)后再次lock,所以wait時候其他線程可以訪問lock的內容;
signal: 處理完數(shù)據(jù)通知其他線程互斥鎖 synchronized
使用 @synchronized(鎖對象) {} 鎖住一塊代碼操作;
能有效處理多線程數(shù)據(jù)安全問題,但是消耗大量CPU資源;DSP中的信號量 dispatch_semaphore_t
使用函數(shù):
dispatch_semaphore_create(num) //創(chuàng)建信號量的初始值
dispatch_semaphore_wait 信號量-1,如果等于0則阻塞,大于0往下執(zhí)行;
dispatch_semaphore_signal 信號量+1CoreData的多線程訪問同步?
OC與Swift混編
- Swift訪問OC
使用 Bridging Header,加入oc文件時系統(tǒng)詢問自動創(chuàng)建,或者自己手動創(chuàng)建,在項目中加入一個新的頭文件命名為"項目工程名-Bridging-Header",然后再設置Build Setting->Swift Compiler ->Object-C Bridging Header的路徑,必須只想文件本身;
在這個頭文件中添加swift需要訪問的OC類的頭文件; - OC訪問Swift
需要配置 Build Setting下的 Packaging:
設置Defines Module為YES,設置Product Module Name,在調用swift
的模塊中加入該名稱的"***-Swift.h"頭文件(這個文件是系統(tǒng)自己創(chuàng)建的),就能夠直接使用OC語法調用swift模塊;
后臺多任務管理機制
http://www.zhihu.com/question/21192280
響應鏈
系統(tǒng)會根據(jù)hittest來處理將定位消息屬于具體哪個窗口;
能響應對象的都是UIResponse的子對象;
app接受的響應會逐級傳遞尋找響應, 形成一個響應鏈,例如一個事件響應鏈:
AppDelegate --> UIApplication --> UIWindow --> UIViewController --> UIView --> UIButton
使用nextResponder函數(shù)可以循環(huán)獲取父級響應對象;
用戶的一個點擊事件信息包括:UITouch和UIEvent;
keychain(Security.framework)
它是一個在所有app之外的sqlite數(shù)據(jù)庫;
Keychain的信息是存在于每個應用(app)的沙盒之外的,所以keychain里保存的信息不會因App被刪除而丟失,在用戶重新安裝App后依然有效,數(shù)據(jù)還在;
NSUserDefaults存儲是不安全的,簡單的信息存儲使用NSUserDefaults即可,但是對于安全性要求比較高的信息,比如賬戶密碼等;
基本函數(shù):SecItemAdd/SecItemUpdate/SecItemCopyMatching/SecItemDelete
100個知識點匯總
http://www.csdn.net/article/2015-01-19/2823604-ios-interview-questions
類的load與initialize靜態(tài)函數(shù)作用
這兩個靜態(tài)方法是可選的,且只有在實現(xiàn)了他們時才會被調用;
- load的作?用
當類對象被引用項目中,runtime會向每一個類對象發(fā)送load消息,這個消息只會被調用一次,要想修改原來類方法及其他,可以在分類的load中進行實現(xiàn); - initialize作用
在整個runtime中也只調用一次,但是它是該類的第一個方法調用之前調用的,用于確保實例初始化前某些條件必須滿足;
2. 內存與多線程知識點
多線程
內存管理
http://www.lxweimin.com/p/dba7e8010cd3
自動釋放池塊與線程
使用局部自動釋放池塊降低最大內存占用率
-
為什么更新UI都在主線程中進行?
因為UIKit不是線程安全的,無法保證多個線程對同一UI的更新操作;
在子線程中是不能進行UI 更新的,我們看到的UI更新其實是子線程代碼執(zhí)行完畢了,又自動進入到了主線程,執(zhí)行了子線程中的UI更新的函數(shù)棧,這中間的時間非常的短,就讓大家誤以為分線程可以更新UI。如果子線程一直在運行,則子線程中的UI更新的函數(shù)棧 主線程無法獲知,即無法更新。
3. UI知識點:
Core Animation / Core Graphics
- Core Animation iOS 系統(tǒng)基本渲染框的OC語言框架
基于CoreGraphics的OC語言封裝動畫處理架構;
動畫執(zhí)行過程都是在后臺操作的,不會阻塞主線程;
動畫使用:
CALayer *layer = [CALayer layer];
CABasicAnimation *animation = [CABasicAnimation animation];
animation.keyPath = @"transform.scale";
animation.toValue = @0;
[layer addAnimation:animation forKey:nil];
CA動畫基礎參考:http://www.lxweimin.com/p/8c1c1697c0ce
- Core Graphics 是底層繪制的C語言框架
實際用到的CG開頭的函數(shù)與變量是指這繪制庫;
可在drawRect函數(shù)中重繪視圖,也可對圖形圖片進行切角,旋轉等轉換處理;
CGContextRef context = UIGraphicsGetCurrentContext();
NSString *str1 = @"畫線";
[self drawText:str1 atPoint:CGPointMake(20.0, 20.0) FontSize:15];
CGContextScaleCTM(context, 1.0, -1.0);
CGContextSaveGState(context);
CGContextRestoreGState();
每一個 UIView 都有一個 graphics context (繪圖上下文),在設備硬件顯示前,繪制的所有視圖都會被渲染到這個上下文中;
iOS 在任何時候需要更新視圖都是通過調用 drawRect 方法;
參考學習:http://www.tuicool.com/articles/jaM7zmN
UIView本身更像是一個一個CALayer的管理器
把UIView看做圖片的話,layer就像是一個圖層,一個圖片是由很多個大小不同的有層次的圖層構成的 uiview也是
UITableView 復用機制
UITableview通常只會顯示當前頁面最大可顯示cell個數(shù)加1,cell離開屏幕后會從隊列中刪除;
- 復用隊列
只有cell被滑出當前頁面的時候,此cell才會被加到復用隊列中,使用dequeueReusableCellWithIdentifier,如果找不到才會調用UITableviewCell的initWithStyle:reuseIdentifier接口創(chuàng)建cell
imageNamed
使用imageNamed方法創(chuàng)建UIImage對象時,圖片會自動加載到系統(tǒng)緩存中不再釋放,會使內存增大
UIImageView圓角
如何提高調價圓角的性能?
- 一般使用clipsToBounds與layer.corneRadius, 但是這個方法會強制Core Animation提前渲染屏幕的離屏繪制,為性能帶來負面影響;
- 使用貝塞爾曲線切割圖片
UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);
[[UIBezierPath bezierPathWithRoundedRect:RECT cornerRadius:RADIUS] addClip];
[image drawInRect:RECT];
UIImage* imageNew = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext();
key window是?
可接收鍵盤輸入等事件的UIWindow,官方文檔如是說:
The key window is the one that is designated to receive keyboard and other non-touch related events. Only one window at a time may be the key window.
使用 makeKeyAndVisible讓一個 UIWindow 變成 key window;
程序主窗口是:[[[UIApplication sharedApplication] delegate] window];
pushViewController 與 presentViewcontroller
- pushViewController提供的是一個棧控制器數(shù)組;
- presentViewcontroller提供的是模態(tài)視圖控制器;
模態(tài)是指一個控制器present另一個控制器,prensenting 與 presented,兩者通過delegate實現(xiàn)交互;所以在沒有navigationController的情況下,使用presentModalViewController能進行controller間的轉換;