在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ iOS/ iOS 中的行為
與四軸無人機的通訊
在沙盒中編寫腳本
結構體和值類型
深入理解 CocoaPods
UICollectionView + UIKit 力學
NSString 與 Unicode
代碼簽名探析
測試
架構
第二期-并發(fā)編程
Metal
自定義控件
iOS 中的行為
行為驅動開發(fā)
Collection View 動畫
截圖測試
MVVM 介紹
使 Mac 應用數(shù)據(jù)腳本化
一個完整的 Core Data 應用
插件
字符串
為 iOS 建立 Travis CI
先進的自動布局工具箱
動畫
為 iOS 7 重新設計 App
XPC
從 NSURLConnection 到 NSURLSession
Core Data 網(wǎng)絡應用實例
GPU 加速下的圖像處理
自定義 Core Data 遷移
子類
與調試器共舞 - LLDB 的華爾茲
圖片格式
并發(fā)編程:API 及挑戰(zhàn)
IP,TCP 和 HTTP
動畫解釋
響應式 Android 應用
初識 TextKit
客戶端
View-Layer 協(xié)作
回到 Mac
Android
Core Image 介紹
自定義 Formatters
Scene Kit
調試
項目介紹
Swift 的強大之處
測試并發(fā)程序
Android 通知中心
調試:案例學習
從 UIKit 到 AppKit
iOS 7 : 隱藏技巧和變通之道
安全
底層并發(fā) API
消息傳遞機制
更輕量的 View Controllers
用 SQLite 和 FMDB 替代 Core Data
字符串解析
終身學習的一代人
視頻
Playground 快速原型制作
Omni 內部
同步數(shù)據(jù)
設計優(yōu)雅的移動游戲
繪制像素到屏幕上
相機與照片
音頻 API 一覽
交互式動畫
常見的后臺實踐
糟糕的測試
避免濫用單例
數(shù)據(jù)模型和模型對象
Core Data
字符串本地化
View Controller 轉場
照片框架
響應式視圖
Square Register 中的擴張
DTrace
基礎集合類
視頻工具箱和硬件加速
字符串渲染
讓東西變得不那么糟
游戲中的多點互聯(lián)
iCloud 和 Core Data
Views
虛擬音域 - 聲音設計的藝術
導航應用
線程安全類的設計
置換測試: Mock, Stub 和其他
Build 工具
KVC 和 KVO
Core Image 和視頻
Android Intents
在 iOS 上捕獲視頻
四軸無人機項目
Mach-O 可執(zhí)行文件
UI 測試
值對象
活動追蹤
依賴注入
Swift
項目管理
整潔的 Table View 代碼
Swift 方法的多面性
為什么今天安全仍然重要
Core Data 概述
Foundation
Swift 的函數(shù)式 API
iOS 7 的多任務
自定義 Collection View 布局
測試 View Controllers
訪談
收據(jù)驗證
數(shù)據(jù)同步
自定義 ViewController 容器轉場
游戲
調試核對清單
View Controller 容器
學無止境
XCTest 測試實戰(zhàn)
iOS 7
Layer 中自定義屬性的動畫
第一期-更輕量的 View Controllers
精通 iCloud 文檔存儲
代碼審查的藝術:Dropbox 的故事
GPU 加速下的圖像視覺
Artsy
照片擴展
理解 Scroll Views
使用 VIPER 構建 iOS 應用
Android 中的 SQLite 數(shù)據(jù)庫支持
Fetch 請求
導入大數(shù)據(jù)集
iOS 開發(fā)者的 Android 第一課
iOS 上的相機捕捉
語言標簽
同步案例學習
依賴注入和注解,為什么 Java 比你想象的要好
編譯器
基于 OpenCV 的人臉識別
玩轉字符串
相機工作原理
Build 過程

iOS 中的行為

作為一個開發(fā)者,我們致力于編寫簡潔并且良好架構的代碼。很多設計模式都可以實現(xiàn)這一點,其中最好的一種是組合模式。組合模式使編寫出的代碼更易于遵循功能單一原則并且可以使我們的類簡化。

為了替代一個功能上服務于不同模塊(就像 data sources 和 delegates )的繁冗的視圖控制器,我們將這些模塊劃分到不同的類中。這個視圖控制器就可可以僅僅負責這些類的配置和協(xié)調它們工作。畢竟,代碼寫的越少,調試和維護代碼的工作量就越少。

那么,行為究竟到底是個什么東西呢?

行為是一個負責實現(xiàn)一個指定功能的對象,比如你可以有一個實現(xiàn)視差動畫的行為。

在這篇文章中所描述的各種行為將可以通過使用 Interface Builder 從而減少大量的代碼書寫,同時使與非編碼人員的協(xié)同工作更高效。然而,就算你不使用 Interface Builder,你也能從中獲益頗多。

許多行為只需要進行設置,而不再需要寫額外的代碼,而對這些行為的配置可以通過 Interface Builder 或者(相同設置方法的)代碼完整地實現(xiàn)。在大多數(shù)情況下,你不必再去用額外的屬性引用它們。

為何使用行為?

大多數(shù)的 iOS 工程中都有繁冗的視圖控制器類,因為大家都習慣于將 80% 的應用邏輯寫在這里。這卻是一個很嚴肅的問題,因為在我們的代碼中視圖控制器這部分的代碼復用是最少的,并且很難對它們(代碼)進行測試與維護。

這里描述的行為幫助我們避免這種場景,那這樣做可以給我們帶來什么好處呢?

更輕量級的視圖控制器

使用行為模式意味著將更多的代碼從視圖控制器中剝離到其他相應的類中。如果你堅持使用這種行為模式,你將最終實現(xiàn)一個非常輕量級的視圖控制器。舉個例子,我所寫的視圖控制器一般不超過 100 行代碼。

代碼復用

由于行為的職責單一,所以它可以非常容易地實現(xiàn)與特定行為和特定應用邏輯的解耦。這使你可以在不同的應用中使用相同的行為代碼。

可測試性

行為都是一些功能簡單的類,其工作原理像一個黑盒。這意味單元測試很容易的完整的覆蓋這部分邏輯。你可以不需要創(chuàng)建真實的視圖,而只需提供模擬對象就能對它們進行測試,

使非程序員能夠改變應用邏輯

如果我們決定通過 Interface Builder 來使用行為,我們就可以教會我們的設計師如何去更改應用邏輯。設計師可以增刪行為并且修改參數(shù),而并不需要理解任何 Objective-C 的相關內容。

這對工作流程有著巨大的好處,針對小團隊來說尤為明顯。

如何構建一個復雜的行為

行為是一些簡單的對象并且不需要太多定制的代碼,但是這里有一些概念可以真正的幫助行為更易使用,并且使用起來更具威力。

運行時屬性

許多開發(fā)者輕視了 Interface Builder 甚至從來不去學習它,正因如此,他們通常不了解 Interface Builder 功能到底有多強大。

運行時屬性是 Interface Builder 使用中最關鍵的特性之一。它們?yōu)槟闾峁┝艘粋€構建自定義類甚至設置 iOS 內置類的屬性的途徑。舉個例子,你是否曾為你的層設置圓角呢?你其實可以直接在 IB 中進行簡單的運行時屬性配置來實現(xiàn)這一點。

http://wiki.jikexueyuan.com/project/objc/images/13-10.png" alt="" />

當在 Interface Builder 中創(chuàng)建行為時,你將重度依賴運行時屬性去設置行為選項。最終將會帶來更多的典型運行時屬性:

http://wiki.jikexueyuan.com/project/objc/images/13-11.png" alt="" />

行為的生命周期

如果一個對象是被 Interface Builder 所創(chuàng)建出來的,除非另外的一個對象對其強引用,否則它將會在被創(chuàng)建后立刻移除。這點對于需要一直在視圖控制器上工作的行為來講并不理想,這樣的行為會希望和視圖控制器擁有同樣的生命周期。

我們可以嘗試在視圖控制器上創(chuàng)建一個對行為強引用的屬性,但這同樣也不完美,有如下的理由:

  • 對于許多行為來說,你可能并不需要在創(chuàng)建并配置之后與其進行交互。
  • 只是為了保持一個對象活躍而創(chuàng)建一個屬性,怎么說都很悲劇。
  • 如果你想要移除一個指定的行為,你需要去清除那個無用了的屬性。

使用 Objective-C 運行時解綁生命周期

不要選擇在視圖控制器上設置強引用來手動綁定一個行為,取而代之,如果有需要的話,我們可以在配置過程中將行為自己賦值為視圖控制器的關聯(lián)對象 (associated object) 。

這意味著,如果我們需要移除一個指定的行為,我們只需要移除對應的配置行為的代碼或者 Interface Builder 對象就可以了,而無需任何額外的改變。

實現(xiàn)如下:

@interface KZBehavior : UIControl

//! object that this controller life will be bound to
@property(nonatomic, weak) IBOutlet id owner;

@end

@implementation KZBehavior

- (void)setOwner:(id)owner
{
    if (_owner != owner) {
        [self releaseLifetimeFromObject:_owner];
        _owner = owner;
        [self bindLifetimeToObject:_owner];
    }
}

- (void)bindLifetimeToObject:(id)object
{
    objc_setAssociatedObject(object, (__bridge void *)self, self,   OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (void)releaseLifetimeFromObject:(id)object
{
    objc_setAssociatedObject(object, (__bridge void *)self, nil,    OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

@end

在這里我們使得已關聯(lián)的對象對一個指定所有者的對象構建了一個強引用。

行為事件

行為可以發(fā)送事件,這個特性非常有用,比如當一個動畫完成時我們就能收到通知。我們可以在 IB 里面通過構建繼承于 UIControl 的行為類來啟用這個特性。一個特性的行為可以調用:

[self sendActionsForControlEvents:UIControlEventValueChanged];

這將允許你將行為關聯(lián)到你的視圖控制器里面的代碼。

基礎行為的例子

那么,什么樣的事情用行為實現(xiàn)會最簡單呢?

這里我們將展示在一個 UIViewController 類(不是自定義的類)中添加一個視差動畫是一件多么容易的事情:

或者需要從你的相冊或者相機中獲取一張圖片?

進階特性

上述的行為都很簡單粗暴,但是,你是否也想知道當我們需要更多進階特性的時候需要做什么?只要肯做,行為的功能可以非常強大,讓我們來看看一些更復雜的例子。

如果你的行為需要一個代理,如 UIScrollViewDelegate ,你將會很快陷入一個困境,你無法在一個特定屏幕上擁有多余一個的行為。但是,我們可以通過實現(xiàn)一個簡單多路代理(遍歷 NSInvocation 命令數(shù)組進行匹配,譯者注)對象來解決這個問題。

@interface MultiplexerProxyBehavior : KZBehavior

//! targets to propagate messages to
@property(nonatomic, strong) IBOutletCollection(id) NSArray *targets;

@end

@implementation MultiplexerProxyBehavior

- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel
{
    NSMethodSignature *sig = [super methodSignatureForSelector:sel];
    if (!sig) {
        for (id obj in self.targets) {
            if ((sig = [obj methodSignatureForSelector:sel])) {
                break;
            }
        }
    }
    return sig;
}

- (BOOL)respondsToSelector:(SEL)aSelector
{
    BOOL base = [super respondsToSelector:aSelector];
    if (base) {
        return base;
    }

    return [self.targets.firstObject respondsToSelector:aSelector];
}

- (void)forwardInvocation:(NSInvocation *)anInvocation
{
    for (id obj in self.targets) {
        if ([obj respondsToSelector:anInvocation.selector]) {
            [anInvocation invokeWithTarget:obj];
        }
    }
}

@end

通過創(chuàng)建一個多路代理的實例,你可以把它作為一個 scroll view (或者其他有代理的對象) 的代理,然后將代理的調用轉發(fā)給所有的行為對象。

總結

行為是一個非常有趣的概念,它可以簡化你的代碼庫,并可以允許在不同的應用間實現(xiàn)許多代碼復用。它們(行為類)將會引領你在團隊中與非編碼人員進行更有效率的工作,并允許他們對應用的行為進行調整和修改。