iOS 總結

iOS是由蘋果公司開發的移動操做系統.數據庫

iOS 簡介

開發語言

Object-C

  • 一般寫做ObjC或OC和較少用的Objective C或Obj-C,是擴充C的面向對象編程語言。OC 徹底兼容 C語言.
  • 面嚮對象語言(C 語言面向過程).
  • 是MAC OSX和IOS開發的基礎語言。

Swift

  • 蘋果於2014年WWDC(蘋果開發者大會)發佈的新開發語言,可與Objective-C*共同運行於Mac OS和iOS平臺,用於搭建基於蘋果平臺的應用程序.
  • Swift和Objective-C共用一套運行時環境,項目中能夠經過橋接的方式互相調用.

開發工具

  • Xcode: 運行在操做系統Mac OS X上的集成開發工具(IDE),由蘋果公司開發。

iOS 基礎

APP 生命週期

iOS 應用有5中狀態:編程

  • Not running 應用還沒啓動或正在運行可是中途被系統中止
  • Inactive 應用正在前臺運行(不接收事件)
  • Active 應用正在前臺運行(接收事件)
  • Background 應用處於後臺運行(還在執行代碼)
  • Suspended 應用處於後臺運行(中止執行代碼) 對應的函數:
//應用將要進入非活動調用 (不接受消息或事件)
- (void)applicationWillResignActive:(UIApplication *)application;
//應用進入活動調用 (接收消息或事件)
- (void)applicationDidBecomeActive:(UIApplication *)application;
//應用進入後臺調用 (設置後臺繼續運行)
- (void)applicationDidEnterBackground:(UIApplication *)application;
//應用將要進入前臺調用
- (void)applicationWillEnterForeground:(UIApplication *)application;
//應用將要退出調用 (保存數據,退出前清理)
- (void)applicationWillTerminate:(UIApplication *)application;
//應用被終止前調用 (內存清理,方式應用被終止)
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application;
//應用載入後調用
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
//應用打開URL時調用
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url;
複製代碼

內存管理機制(引用計數)

簡介

OC 引入引用計數機制來跟蹤並管理對象的生命週期. iOS 5以前採用 MRC(手動內存管理) 管理內存.需用開發人員手動調用reatain,release等方法.
iOS 5以後採用 ARC(自動內存管理) 管理內存,不用開發人員去關心引用計數的變化.swift

操做 對應 OC 方法 引用計數變化
建立對象 alloc,new 等 生成對象,引用計數設置爲 1
持有對象 reatain 引用計數 +1
釋放對象 release 引用計數 -1
廢棄對象 dealloc 引用計數爲0,釋放內存

alloc 與 dealloc,reatain與 release 成對存在, 誰建立誰釋放,誰retain誰釋放
只有當引用計數爲 0 是對象纔會銷燬回收內存.設計模式

工做原理

  • 當咱們建立(alloc)一個新對象A的時候,它的引用計數從零變爲 1.
  • 當有一個指針指向這個對象A,也就是某對象想經過引用保留(retain)該對象A時,引用計數加 1.
  • 當某個指針/對象再也不指向這個對象A,也就是釋放(release)該引用後,咱們將其引用計數減 1.
  • 當對象A的引用計數變爲 0 時,說明這個對象再也不被任何指針指向(引用)了,這個時候咱們就能夠將對象A銷燬,所佔內存將被回收,且全部指向該對象的引用也都變得無效了。系統也會將其佔用的內存標記爲「可重用」(reuse).

屬性

聲明

@property(nonatomic, strong)UITextField *textField;
OC 採用 '@property' 聲明對象, 會默認生成一個 '_textField' 成員變量與與之對應的 'setter/getter' 方法.緩存

屬性修飾符

修飾符 描述 引用計數變化
copy 複製,建立一個新對象,一般修飾 NSString,NSArray,NSDictionary,NSSet 新對象引用計數爲 1,舊對象不變
retain 釋放舊對象,主要用於(MRC) 釋放舊對象,計數 -1,新對象 retain, 計數 +1
strong 強引用,與 retain類似 釋放舊對象,計數 -1,新對象 retain, 計數 +1
assign 修飾基本數據類型 不變
weak 與assign相似,修飾對象,對消銷燬後自動變成 nil,主要用於修飾 delegate 不變
readwrite 可讀寫,生成 setter 與 getter 方法 -
readonly 只讀,只爲屬性生成 getter 方法 -
nonatomic 非原子屬性,不爲 setter 方式加鎖,非線程安全,一般採用這種,執行效率高 -
atomic 原子屬性,爲 setter 方式加鎖,線程安全 -

注意問題

  • 對 block 修飾 Strong,copy 均可以,建議使用 copy. block 聲明默認爲棧變量,爲了可以在block的聲明域外使用,因此要把block拷貝(copy)到堆,因此說爲了block屬性聲明和實際的操做一致,最好聲明爲copy。
  • NSString,NSArray,NSDictionary,NSSet 建議使用 copy. 當將 NSMutableString 賦值給 NSString 時, strong 修飾只會進行淺拷貝(引用計數 +1),NSMutableString與NSString 指向同一內存空間,NSMutableString修改時NSString會隨之改變. copy 修飾深拷貝(複製內存單元),NSMutableString與NSString 指向不一樣內存空間,NSMutableString修改時NSString不會改變.
  • __weak __Strong __block 在 block 使用時有時爲了不形成循環引用會用 __weak __Strong 進行修飾下. 有時在 block 中,爲了不對象過早釋放用 __Strong 修飾.

數據持久化

  • 讀寫文件: 比較複雜,對對象保存須要進行歸檔反歸檔處理.
  • 雲端存儲: 須要後臺配合.
  • 本地數據庫(SQLite,CoreDate): CoreDate 是 iOS5 以後出現的,實質是對 SQLite 的封裝.
  • NSUserDefaults: 系統自帶的持久化類,進行簡單數據存儲(用戶登陸信息等).

類繼承關係(單繼承)

iOS 全部的類都繼承與 NSObject, 主要分爲 UI 和 NS 兩大類. UI 主要爲視圖, NS 爲數據操做. 圖解: ![UI 系](iOS 總結_1.png) ![UI 系](iOS 總結_2.png)安全

其餘: UIViewController 生命週期: 初始化 --> loadView --> viewDidLoad --> viewWillAppear --> viewWillLayoutSubviews --> viewDidLayoutSubviews --> viewDidAppear --> viewWillDisappear --> viewDidDisappear --> deallocapp

傳值

  • 屬性傳值
  • block 傳值
  • 代理傳值
  • 通知傳值
  • 單例傳值
  • 持久化傳值

協議與代理

在iOS開發中,Protocol是一種常常用到的設計模式,蘋果的系統框架中也廣泛用到了這種方式,好比UITableView中的. 協議聲明:框架

#import <Foundation/Foundation.h>

@protocol ProtocolDelegate <NSObject> // 必須實現方法 @required - (NSString*)getName; // 可選方法 @optional - (NSString*)getAge; @end 複製代碼

協議使用異步

  • 協議是一系列標準的方法列表,能夠被任何類實現.
  • 協議中不能聲明成員變量,只要一個類遵照了這個協議,也至關於擁有了該協議中全部方法的聲明.
  • 父類遵照了該協議,那麼它的子類也就都遵照該協議,能夠遵照多個協議.

代理: 當前類(委託者)將一些操做委託給另外一個類(代理)去完成. 委託者須要作的事:編程語言

  • 建立協議(也就是代理要實現的方法)
  • 聲明委託變量
  • 設置代理(也能夠在代理中設置)
  • 利用委託變量來調用協議方法(也就是讓代理者開始執行協議) 代理須要作的事:
  • 遵循協議
  • 實現協議方法

數據請求

iOS 中級

響應者鏈

  • 響應對象: 繼承自UIResponder的對象稱之爲響應者對象.
  • 響應事件: 觸摸事件、點按事件(長按,屢次點擊,輕點等)、加速事件和遠程控制.
  • 響應者鏈: 由多個響應者組合起來的鏈條

事件產生與傳遞

  • 發生觸摸事件後,系統會將該事件加入到一個由UIApplication管理的事件隊列中.
  • UIApplication會從事件隊列中取出最前面的事件,並將事件分發下去以便處理,一般,先發送事件給應用程序的主窗口(keyWindow).
  • 主窗口會在視圖層次結構中找到一個最合適的視圖來處理觸摸事件,這也是整個事件處理過程的第一步.
  • 找到合適的視圖控件後,就會調用視圖控件的touches方法來做具體的事件處理.
  • 若是調用了[super touches….];就會將事件順着響應者鏈條往上傳遞,傳遞給上一個響應者,調用上一個響應者的touches….方法 注意: 若是父控件不能接受觸摸事件,那麼子控件就不可能接收到觸摸事件 ![UI 系](iOS 總結_3.png)

事件響應

  • 若是視圖不響應事件,則將其傳遞給它的父視圖
  • 在最頂級的視圖層次結構中,若是都不能處理收到的事件或消息,則其將事件或消息傳遞給UIWindow對象進行處理
  • 若是UIWindow對象也不處理,則其將事件或消息傳遞給UIApplication對象處理
  • 若是UIApplication也不能處理該事件或消息,則將該事件丟棄 如何判斷上一個響應者
    • 若是當前這個view不是控制器的view, 那麼它的父控件就是上一個響應者
    • 若是當前這個view是控制器的view, 那麼控制器就是上一個響應者

UIView不能接收觸摸事件的狀況

  • 不容許交互: userInteractionEnabled = NO(eg: UIImageView)
  • 隱藏
  • 透明度: 透明度<0.01
  • 子視圖超出了父視圖區域
  • 當前 View 被遮擋

分類(category)與類擴展(extension)

分類

  • 在不改變原類的基礎上爲一個類擴展方法.
  • 主要用法爲系統類擴展方法
  • 不可添加成員變量. 若是要添加成員變量須要本身實現 setter 和 getter 方法(runtime).
  • 分類文件(.h,.m),覺得 Person 添加分類爲例,能夠經過 Person 實例對象直接調用 playFootBall 方法(分類方法執行優先級高於本類).

Person+sport.h

#import "Person.h"

@interface Person (sport)

- (void)playFootBall;

@end

複製代碼

Person+sport.m

#import "Person+sport.h"

@implementation Person (sport)

- (void)playFootBall {
    NSLog(@"playFootBall");
}

@end

複製代碼

類擴展

類擴展是分類的一個特例,爲一個類添加一些私有成員變量和方法(經常使用). 類擴展定義的方法,須在類的implement 中實現 類擴展能夠定義屬性 聲明:

#import "Person.h"

@interface Person ()
- (void)say;
@end
複製代碼

分類與繼承

iOS 中分類(Categories) 和 繼承(Inherit)有相同的功能,但在一些細節上又有差別,如何選擇。 使用繼承:

  • 擴展方法與原方法名相同,還須要使用父類方法.
  • 擴展類屬性(分類不能擴展類屬性) 使用分類:
  • 爲系統類添加方法(eg: 爲 NSString 添加字符串校驗).
  • 開發人員針對本身的類,將相關方法分組到不一樣的文件.

UITableView 重用機制

UITableView 是 iOS 開發中最長用的控件,爲了節省內存開銷, UITableView 使用重用機制(重用 cell 單元格).

使用重用機制建立 cell

  • 定義重用標示(static 修飾字符串).
  • 在重用池取出 cell.
  • 若重用池沒有可用 cell, 建立新的 cell.
static NSString *reuseIndentifier = @"MyCell";  
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIndentifier];  
if (!cell) {  
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIndentifier];  
}
複製代碼

原理

UITableView 維護這兩個隊列,單前可視 cell 隊列 visiableCells, 可重用 cell 隊列 reusableTableCells(重回池). 在最初visiableCells, reusableTableCells 都爲空, "UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];" 獲取 cell 爲 nil, 執行 cell 初始化方法建立顯示並存入到 visiableCells.若是屏幕最多顯示 cell 個數爲10,當加載完第11個 cell 時建立的第一個 cell 在 visiableCells 移除加入到 reusableTableCells 中,因此在加載第12個 cell 時只需在 reusableTableCells 取出 cell 便可.第十二個 cell 加載完成後建立的第二個 cell 移出 visiableCells 進入 reusableTableCells 中,依次類推(理論講只需建立11個 cell 就可).

遇到問題和優化

  • 重取出來的cell是有可能已經捆綁過數據或者加過子視圖的,形成視圖疊加混亂的現象
    • 刪除已有數據或子視圖.
    • 放棄了重用機制,每次根據indexPath獲取對應的cell返回(內存銷耗特大).
  • 結合 MJFresh 實現數據分頁加載.
  • 結合 SDWebImage 實現 cell 中圖片異步加載以及緩存.
相關文章
相關標籤/搜索