<center>整理
MRC和ARC區(qū)別
- MRC: (Manual Reference Counting)也就是非ARC,在Xcode4之前争群,Object_C的內存管理就需要開發(fā)人員手動維護。
- ARC: (Automatic Reference Counting)也就是ARC鞭莽,翻譯成中文就是:【自動引用計數(shù)】吁峻,不需要開發(fā)人員手動維護,系統(tǒng)會在合適的時候調用內存管理方法费尽。
內存區(qū)
五大內存區(qū)域分別為
- 棧區(qū):創(chuàng)建臨時變量時由編譯器自動分配,在不需要時自動清除的<font color="red">變量的存儲區(qū)</font>羊始。里面的變量通常為<font color="red">局部變量</font>旱幼、<font color="red">函數(shù)的參數(shù)</font>等。
- 堆區(qū):就是那些有new alloc創(chuàng)建的對象所分配的內存塊突委,它們的釋放系統(tǒng)不會主動去管柏卤,由開發(fā)者去告訴系統(tǒng)什么時候去釋放。
- 全局區(qū):<font color="red">全局變量</font>和<font color="red">靜態(tài)變量</font>被分配到同一塊內存中鸯两。
- 常量區(qū):存放常量的區(qū)域闷旧,不允許修改。
- 代碼區(qū): 存放函數(shù)的二進制代碼區(qū)域钧唐。
- 自由存儲區(qū)(五大區(qū)域之外區(qū)):由malloc等分配的內存塊忙灼,它們有free在釋放
說說地圖的使用
- 首先要在info.plist文件中添加配置
- NSLocationAlwaysUsageDescription
- NSLocationWhenInUseUsageDescription
- 地圖坐標系
- 百度地圖
說說hybird應用的技術 ?钝侠?该园?
TableView的使用 tableViewcell基類的設計
重用機制的正確使用
對于復雜的cell 盡量使用純代碼布局 因為 xib、storyBoard 需要系統(tǒng)自動轉碼
緩存高度 (如果計算復雜 子線程去計算)
異步加載圖片 SDWebimage 已實現(xiàn)
減少使用透明視圖
減少subviews的數(shù)量和層級數(shù)
不要動態(tài)的在cell上添加view 可以在初始化的時候添加 然后控制顯示 隱藏
避免subview的層級調整
-
圓角優(yōu)化
- cell中出現(xiàn)的圓角還是比較常見的 通常我們處理圓角都會使用
imageView.layer.cornerRadius = 10; imageView.layer.maskToBounds = YES
這樣處理就會造成離屏渲染 性能損耗
-
使用貝塞爾曲線UIBezierPath和Core Graphics框架畫出一個圓角帅韧。
UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)]; imageView.image = [UIImage imageNamed:@"myImg"]; //開始對imageView進行畫圖 UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 1.0); //使用貝塞爾曲線畫出一個圓形圖 [[UIBezierPath bezierPathWithRoundedRect:imageView.bounds cornerRadius:imageView.frame.size.width] addClip]; [imageView drawRect:imageView.bounds]; imageView.image = UIGraphicsGetImageFromCurrentImageContext(); //結束畫圖 UIGraphicsEndImageContext(); [self.view addSubview:imageView];
-
使用CAShapeLayer和UIBezierPath設置圓角(比較處理方式1更優(yōu))
UIImageView*imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100,100,100,100)]; imageView.image = [UIImage imageNamed:@"myImg"]; UIBezierPath*maskPath = [UIBezierPath bezierPathWithRoundedRect:imageView.bounds byRoundingCorners:UIRectCornerAllCorners cornerRadii:imageView.bounds.size]; CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init]; //設置大小 maskLayer.frame = imageView.bounds; //設置圖形樣子 maskLayer.path = maskPath.CGPath; imageView.layer.mask = maskLayer; [self.view addSubview:imageView];
- CAShapeLayer
- CAShapeLayer繼承于CALayer里初,可以使用CALayer的所有屬性值.
- CAShapeLayer需要貝塞爾曲線配合使用才有效果
- CAShapeLayer動畫渲染直接提交到手機的GPU當中,相較于view的drawRect方法使用CPU渲染而言忽舟,其效率極高双妨,能大大優(yōu)化內存使用情況。
- 總而言之叮阅,CAShapeLayer的內存消耗少刁品,渲染速度快。因此處理方式2較處理方式1更優(yōu)浩姥。
- CAShapeLayer
使用一個透明底圓形的同顏色的邊的圖直接蓋上 直接避免了離屏渲染
直接使用切過圓角的圖
KVC和KVO的原理 [詳解點擊](url https://blog.csdn.net/bolted_snail/article/details/82147675)
- KVC: <font color="red">KeyValueCoding</font> 俗稱“鍵值編碼”, 是一個基于NSKeyValueCoding非正式協(xié)議的機制挑随,就是直接通過key值對對象的屬性進行存取操作,而不是通過明確的存取方法勒叠。
<font color="red">注:NSObject是定義了KVC的兜挨,所以繼承NSObject的對象都支持KVC膏孟,基本上所有的OC對象都支持KVC。</font>
- setValue:forKey:
- setKey:
- _setKey:
- 查看+ (BOOL)accessInstanceVariablesDirectly; 是否返回YES(默認YES)拌汇,如果是YES繼續(xù)執(zhí)行柒桑,如果是NO拋出異常NSUnknownException。
- _key
- _isKey
- key
- isKey
- NSUnknownException
- valueForKey:
- getKey
- key
- isKey
- _key
- 查看+ (BOOL)accessInstanceVariablesDirectly; 是否返回YES(默認YES)担猛,如果是YES繼續(xù)執(zhí)行幕垦,如果是NO拋出異常NSUnknownException。
- _key
- _isKey
- key
- isKey
- NSUnknownException
- KVO <font color="red">KeyValueObserving</font> 俗稱“鍵值監(jiān)聽”傅联,可以用于監(jiān)聽某個對象的屬性值的改變。 KVO是通過isa-swizzling技術實現(xiàn)的(這句話是整個KVO實現(xiàn)的重點)疚察。在運行時根據(jù)原類創(chuàng)建一個中間類蒸走,這個中間類是原類的子類,并動態(tài)修改當前對象的isa指向中間類貌嫡。并且將class方法重寫比驻,返回原類的Class。所以蘋果建議在開發(fā)中不應該依賴isa指針岛抄,而是通過class實例方法來獲取對象類型别惦。
自動釋放池 AutoreleasePool
AutoreleasePool是OC中一種內存自動回收機制,它可以延時加入AutoreleasePool中的變量release的時機夫椭,在正常情況下掸掸,創(chuàng)建的變量會在超出其作用域的時候release,但是如果將變量加入到AutoreleasePool蹭秋,那么release將延時執(zhí)行扰付。
-
AutoreleasePool是以棧為節(jié)點,通過雙向鏈表的形式組合而成仁讨,AutoreleasePool是與線程一一對應的羽莺。
- 雙向鏈表的單位是節(jié)點,從頭結點開始一直到尾結點洞豁,每一個節(jié)點都會有一個父指針和子指針盐固,父指針指向前一個的節(jié)點,子指針指向后一個節(jié)點丈挟,而頭節(jié)點的父指針指向NULL刁卜,尾節(jié)點的子指針指向NULL。這樣就把椊负澹空間通過雙向鏈表的形式連接起來了长酗。
-
在AutoreleasePool中有四個變量分別為:
id *next AutoreleasePoolPage *const parent AutoreleasePoolPage *child pthread_t const thread
- id *next 一個id類型的指針,指向的是下一個可存儲對象的位置桐绒。
- AutoreleasePoolPage *const parent 這個就是當前page父節(jié)點page的地址指針夺脾。
- AutoreleasePoolPage *child 子節(jié)點的地址指針之拨。
- pthread_t const thread 這個變量中記錄了線程的情況,所以說自動釋放池是與線程一一對應的關系咧叭。
代理和Block
- NotificationCenter 通知中心:一對多蚀乔,在app中如果很多控制器需要知道同一件事情,應該使用通知
- delegate 代理委托:一對一 對同一個協(xié)議菲茬,一個對象只能設置一個代理吉挣,所以單利對象就不能使用代理 代理更注重過程
- block 閉包:一對一 相對于delegate block有以下特點
- 寫法更簡單
- block注重結果的傳輸
- block需要注意防止循環(huán)引用
單利為什么不使用代理
單例只有一個對象且存在APP的整個生命周期,1婉弹、如果你先設置為A的代理睬魂,然后設置成B的代理,A的代理就會失效镀赌;2氯哮、代理一般是weak修飾為的就是不再使用的時候自動釋放,而單例你是釋放不了的商佛,這樣就會存在內存泄漏 3喉钢、因為它一直存活還是某個對象的代理就可能引發(fā)很難查找的問題
load與initialize
load
- 編譯器自動調用 每個類都會調用 并且在main函數(shù)之前調用
- 每個類的調用順序跟項目加載的順序有關 項目 -> TARGETS -> Build Phases -> Compile Sources 從上往下調用
- 繼承關系并且父類實現(xiàn)的分類 父類 -> 子類 -> 分類
initialize
- 類初始化時調用 無論初始化多少次只會在第一次初始化時調用
- 如果類有分類那么分類的initialize方法會把類本身分initialize方法替換掉
- 繼承關系 父類 -> 子類
block
block原理,本質
- NSGlobalBlock (_NSConcreteGlobalBlock) 數(shù)據(jù)區(qū)
- NSStackBlock (_NSConcreteStackBlock) 棧區(qū)
-
NSMallocBlock (_NSConcreMallocBlock) 堆區(qū)
繼承自NSBlock -> NSObject
...
__block的作用良姆,有什么使用注意點
__block本身無法避免循環(huán)引用 但是我們可以在block內部手動把blockObj賦值為nil的方式在避免循環(huán)引用
__block修飾的變量在block內外都是唯一的
__weak本身可以避免循環(huán)引用肠虽,但是會導致外部對象釋放后,block內部也訪問不到這個對象玛追。我們可以通過在block內部聲明一個__strong的變量在指向weakObj税课,使外部對象既能在block內部保持住,又能避免循環(huán)引用的問題豹缀。
block的屬性修飾為什么用copy伯复,使用block需要注意什么
block一旦沒有進行copy操作 就不會在堆上
block在堆上 程序員就可以對block做內存管理等操作,可以控制block的生命周期
block在修改NSMutableArray 需不需要添加__block
不需要
delegate用 weak 和 assign 修飾的區(qū)別
- strong:該對象強引用delegate邢笙,外界不能銷毀delegate對象啸如,會導致循環(huán)引用
- assign:也有weak的功效,不會產生循環(huán)引用氮惯。但是assign是指針賦值叮雳,不對引用計數(shù)操作,使用之后如果沒有置為nil妇汗,可能會出現(xiàn)野指針
- weak:指明該對象并不負責保持delegate對象
事件傳遞和響應者鏈
只有繼承了UIResponder的類才能處理響應事件
CALayer繼承自NSObject 無法處理響應事件
事件傳遞:UIApplication -> UIWindow -> UIView
響應者鏈:UIView -> UIViewController -> UIWindow -> UIApplication
擴大點擊范圍
// 此方法返回的View是本次點擊事件需要的最佳View
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
// 判斷一個點是否落在范圍內
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
// 擴大按鈕的點擊范圍
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event {
CGRect bounds = self.bounds;
bounds = CGRectInset(bounds, -10, -10);
// CGRectContainsPoint 判斷點是否在矩形內
return CGRectContainsPoint(bounds, point);
}
Runtime
Runtime介紹
..................
KVO && KVC
[self class] [super class]
atomic
autoreleasepool
autoreleasePool是由多個autoreleasePoolPage組成的一個雙向鏈表
autoreleasepoolpush -> 靜態(tài)的 push -> autoreleasepoolfast
hotpage() 有page并且page沒滿 (4096字節(jié))就執(zhí)行add 如果page滿了 就執(zhí)行autoreleasepagefullpage 如果沒有page就執(zhí)行 AutoreleaseNopage
autoreleasepagefullpage方法 從傳入的pa個開遍歷整個雙向鏈表 直到 找到一個未滿的page或者 創(chuàng)建一個的新的page 上一個的page的child指向新的創(chuàng)建的page 新創(chuàng)建的page的parent指向上一個page 然后將新找到或者創(chuàng)建的page設置成hotpage 在執(zhí)行add方法
AutoreleaseNopage方法 創(chuàng)建見一個新的Autoreleasepoolpage (新創(chuàng)建的沒有parent指針)
并把新的Autoreleasepoolpage設置為hotpage 然后add一個哨兵對象來確保pop是不會異常 最后add(obj)
Autoreleasepoolpop -> 靜態(tài)的pop 從最下方調用pop 依次釋放棧中的對象 直到遇到標識符
事件傳遞和響應機制
runloop
weak
weak 是runtime維護了就是一個哈希表 key是指向對象的地址 value是weak指針的地址數(shù)組
當dealloc調用時 runtime會以obj為key找到對應的value 依次釋放
http 和 https
TCP/IP 四層模型
- 應用層 : FTP 帘不、HTTP、DNS杨箭、SMTP
- 運輸層 :TCP寞焙、UDP
- 網(wǎng)絡層 : IP
- 鏈路層 :硬件接口
OSI參考模型
- 應用層:應用層協(xié)議, HTTP、FTP、SMTP
- 表示層 :加密解密捣郊、壓縮解壓
- 會話層 : 不同機器上用戶之間及管理會話
- 傳輸層 : 接受上一層數(shù)據(jù), 必要的時候把數(shù)據(jù)進行分割, 交給網(wǎng)絡層, 保證數(shù)據(jù)段有效到達對端
- 網(wǎng)絡層 : 控制子網(wǎng)的運行辽狈、邏輯地址、分組傳輸呛牲、路由選擇
- 數(shù)據(jù)鏈路層:物理尋址
- 物理層:原始比特流傳輸
HTTP
超文本傳輸協(xié)議, 默認端口是 80
特點
- 無狀態(tài): 每次請求都是獨立的, 兩個請求之間沒有聯(lián)系, 但是會引入 Cookie 和 Session 機制來關聯(lián)請求
- 無連接:服務端收到客戶端請求后, 響應完成并收到客戶端的應答之后, 立即斷開連接
請求報文
- 請求行
- 方法 : GET 刮萌、POST 、HEAD娘扩、PUT着茸、DELETE、OPTIONS
- URL 字段
- HTTP協(xié)議版本號
- 請求頭
- Accept: 瀏覽器可以接受的 MIME 類型
- Accept-Encoding:瀏覽器支持的編碼類型
- Accept-Language: 瀏覽器支持的語言
- Content-Length : 請求消息的正文長度
- Content-Type : 客戶端接受服務器返回的文件類型
- User-Agent : 請求的用戶信息, 瀏覽器類型
- Host : 給出接受請求的服務器主機名和端口號
響應報文
- 響應行
- 報文協(xié)議及版本
- 狀態(tài)碼及描述
- 響應頭
- Content-Length : 響應消息長度
- Content-Type : 當前內容的 MIME 類型
- Server : 服務器名稱
- Set-Cookie : 設置 cookie
- 響應碼
- 1xx : 臨時響應, 需要請求者繼續(xù)執(zhí)行操作
- 2xx: 成功處理了請求的狀態(tài)碼
- 3xx : 如果要完成請求, 需要進一步操作, 重定向
- 4xx : 請求出錯
- 5xx: 服務器內部錯誤
HTTPS
默認端口號是 443
- 客戶端請求 https 連接, 服務器收到請求后會把證書信息(包含公鑰和簽名) 返回給客戶端
- 客戶端會校驗這個證書簽名的有效性從而獲取到公鑰
- 客戶端隨機生成會話密鑰(對稱加密), 然后利用證書里面的公鑰將會話密鑰加密, 連同加密后的內容傳送給服務端
- 服務器利用私鑰解密出會話密鑰, 然后解密出內容
- 服務端利用會話密鑰通信
HTTPS 優(yōu)缺點
優(yōu)點
- 可以認證用戶和服務器, 確保數(shù)據(jù)發(fā)送到正確的客戶端和服務端
- 防止數(shù)據(jù)在傳輸過程中不被竊取琐旁、改變, 確保數(shù)據(jù)的完整性
缺點
- 比較耗時, 頁面的加載時間延長 50%, 增加 10% 和 20%的耗電
- SSL 證書要錢
- https 連接緩存不如 http 高效
- 并非絕對安全, 掌握CA證書機構涮阔、加密算法的組織任然可以進行中間人形式的攻擊
http 和 https 的區(qū)別
- http 協(xié)議沒有加密, https 對傳輸數(shù)據(jù)加密, 保證用戶信息
- http 默認端口是80, https 默認端口是443
- http 無需證書, 而 https 需要購買證書
http 1.x 和 http 2.0 的區(qū)別
- 新的二進制格式: 1.x 的解析是基于文本的, 2.0是二進制格式
- 多路復用: 連接共享。 1.x 每次請求都建立一個鏈接, 用完關閉, 串行單線程處理, 后面的請求等待前面請求返回才能執(zhí)行灰殴。 2.x 多個請求同時在一個連接上并行執(zhí)行
- header壓縮: 1.x 的header 有大量信息每次都要重復發(fā)送, 2.0 使用 encoder 來減少傳輸?shù)?header 大小
- 服務端推送
get 和 post 的區(qū)別
- get 的請求放在 URL 上, 參數(shù)之間以 & 相連, post 請求放在 http body 內
- get 的提交數(shù)據(jù)最大有限制, 跟環(huán)境有關系, post 理論上沒有限制, 大小由服務器設定
- get 產生一個 TCP 數(shù)據(jù)包, 瀏覽器會一起發(fā)送 header 和 data, 服務器返回200 post 有些服務器是只發(fā)一個 TCP 數(shù)據(jù)包, 有些會先發(fā)送header澎语, 服務器返回100后, 再發(fā)送data, 返回200
- get 請求會主動 cache, post 不會, 除非手動設置
- get 在瀏覽器返回時是無害的, post 會再次提交請求