ReactiveCocoa鏈式編程初探

来源:http://www.cnblogs.com/zhouxubin/archive/2016/06/08/5569113.html
-Advertisement-
Play Games

在使用 masonry 框架實現自動佈局時,在程式里為一個佈局穿插著6行左右這樣的代碼 [View mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(anotherView); make.left.equalTo(a ...


在使用 masonry 框架實現自動佈局時,在程式里為一個佈局穿插著6行左右這樣的代碼

 

[View mas_makeConstraints:^(MASConstraintMaker *make) {

      make.top.equalTo(anotherView);

      make.left.equalTo(anotherView);

      make.width.mas_equalTo(@60);

      make.height.mas_equalTo(@60);

}];

一直覺得不夠漂亮,希望有個一行代碼設置約束的框架,我曾嘗試過在masonry上封裝一個類別 UIView+HKSetConstraints ,用起來也不順手,總覺得不夠味,直到我見到了 SDAutoLayout , 真正的實現了一句代碼實現自動佈局,加上研究ReactiveCocoa時看到的最快讓你上手之ReactiveCocoa基礎篇(下麵會給出鏈接)提到編程思想,才明瞭Masonry 和 SDAutoLayout一點實現思路:鏈式編程思想,分享下自己的心得,希望是大家喜歡的東西, ps: 這是本人第一次分享文章,寫的不好請指出,下次好改正。

 

接下來的部分摘自:最快讓你上手之ReactiveCocoa基礎篇

先簡單介紹下目前咱們已知的編程思想。

1 面向過程:處理事情以過程為核心,一步一步的實現。

2 面向對象:萬物皆對象

3 鏈式編程思想:是將多個操作(多行代碼)通過點號(.)鏈接在一起成為一句代碼,使代碼可讀性好。a(1).b(2).c(3)

  • 鏈式編程特點:方法的返回值是block,block必須有返回值(本身對象),block參數(需要操作的值)

  • 代表:Masonry框架。

4 響應式編程思想:不需要考慮調用順序,只需要知道考慮結果,類似於蝴蝶效應,產生一個事件,會影響很多東西,這些事件像流一樣的傳播出去,然後影響結果,借用面向對象的一句話,萬物皆是流。

  • 代表:KVO運用。

5 函數式編程思想:是把操作儘量寫成一系列嵌套的函數或者方法調用。

  • 函數式編程特點:每個方法必須有返回值(本身對象),把函數或者Block當做參數,block參數(需要操作的值)block返回值(操作結果)

  • 代表:ReactiveCocoa。

  • 用函數式編程實現,寫一個加法計算器,並且加法計算器自帶判斷是否等於某個值.

我們這裡以鏈式編程思想代碼實現一個計算器:

 

 

 

#import

@class CaculatorMaker;

@interface NSObject (CaculatorMaker)

 

//計算

+ (int)makeCaculators:(void(^)(CaculatorMaker *make))caculatorMaker;

 

@end

 

 

#import "NSObject+CaculatorMaker.h"

#import "CaculatorMaker.h"

 

@implementation NSObject (CaculatorMaker)

 

//計算

+ (int)makeCaculators:(void(^)(CaculatorMaker *make))block

{

    CaculatorMaker *mgr = [[CaculatorMaker alloc] init];

    block(mgr);

    return mgr.iResult;

}

 

@end

 

 

#import

 

@interface CaculatorMaker : NSObject

 

@property (nonatomic, assign) int iResult;

 

//加法

- (CaculatorMaker *(^)(int))add;

 

//減法

- (CaculatorMaker *(^)(int))sub;

 

//乘法

- (CaculatorMaker *(^)(int))muilt;

 

//除法

- (CaculatorMaker *(^)(int))divide;

 

@end



 

#import "CaculatorMaker.h"

 

@implementation CaculatorMaker

 

- (CaculatorMaker *(^)(int))add

{

   return ^(int value)

    {

        _iResult += value;

        return self;

    };

}

 

@end

 

調用:

 

int iResult = [NSObject makeCaculators:^(CaculatorMaker *make) {

     make.add(1).add(2).add(3).divide(2);

   }];


分析下這個方法執行過程:

第一步:NSObject 創建了一個block, 這個block里創建了一個CaculatorMaker對象make,並返回出來

第二步:這個對象make調用方法add時,裡面持有的屬性iResult做了一個加法,並且返回自己,以便可以接下去繼續調用方法。 

這就是鏈式編程思想的一個很小但很明瞭的例子。

 

 

現在我們以 Masonry 舉例:

我們看看Masonry的

- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *make))block;

 

- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *))block {

    self.translatesAutoresizingMaskIntoConstraints = NO;

    MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self];

    block(constraintMaker);

    return [constraintMaker install];

}

 

是不是跟我們的計算器的類別一個樣????? 

我們再來看看它的

- (MASConstraint * (^)(id attr))mas_equalTo;

 

- (MASConstraint * (^)(id))mas_equalTo {

    return ^id(id attribute) {

        return self.equalToWithRelation(attribute, NSLayoutRelationEqual);

    };

}


看看它的self.equalToWithRelation實現:

 

- (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation {

    return ^id(id attribute, NSLayoutRelation relation) {

        if ([attribute isKindOfClass:NSArray.class]) {

            NSAssert(!self.hasLayoutRelation, @"Redefinition of constraint relation");

            NSMutableArray *children = NSMutableArray.new;

            for (id attr in attribute) {

                MASViewConstraint *viewConstraint = [self copy];

                viewConstraint.secondViewAttribute = attr;

                [children addObject:viewConstraint];

            }

            MASCompositeConstraint *compositeConstraint = [[MASCompositeConstraint alloc] initWithChildren:children];

            compositeConstraint.delegate = self.delegate;

            [self.delegate constraint:self shouldBeReplacedWithConstraint:compositeConstraint];

            return compositeConstraint;

        } else {

            NSAssert(!self.hasLayoutRelation || self.layoutRelation == relation && [attribute isKindOfClass:NSValue.class], @"Redefinition of constraint relation");

            self.layoutRelation = relation;

            self.secondViewAttribute = attribute;

            return self;

        }

    };

}


的確是返回自己,所以這正是它的鏈式編程思想的體現。

由於本人沒有繼續研究Masonry, 研究神的同學可以繼續分享它的更詳細的思路。

關於鏈式編程,我希望沒接觸過的同學以後封裝類似的類時,可以朝著這方向思考,少走彎路,謝謝


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Python支持四種不同的數值類型,包括int(整數)long(長整數)float(浮點實際值)complex (複數),本文章向碼農介紹python 四種數值類型,需要的朋友可以參考一下。 數字數據類型存儲數值。他們是不可改變的數據類型,這意味著改變數字數據類型的結果,在一個新分配的對象的值。Nu ...
  • 我們可以用groovy編寫日常的批處理腳本,類似windows下的bat或者unix下的shell。其具體的編寫方式非常簡單,比如我們想要執行一個dir的命令,只要編寫一個test.groovy,其中內容為: println 'cmd /c dir'.execute().text 因為dir這個命令 ...
  • //資源和認證伺服器不相同http://xxxx:8080/flowAuth/oauth/authorize?client_id=jerry&redirect_uri=http%3a%2f%2fxxxx%3a8080%2fAuthProvider%2ftest%2findex.do&response ...
  • python3+任務計劃實現的人人影視網站自動簽到 這是一個自動化程度較高的程式,運行本程式後會從chrome中讀取cookies用於登錄人人影視簽到, 並且會自動添加一個windows 任務計劃,這個任務計劃每天下午兩點會執行本程式進行簽到。 sys.executable == 'C:\\Pyth ...
  • list 是 Python 中使用最頻繁的數據類型, 標準庫裡面有豐富的函數可以使用。不過,如果把多維列表轉換成一維列表(不知道這種需求多不多),還真不容易找到好用的函數,要知道Ruby、Mathematica、Groovy中可是有flatten的啊。如果列表是維度少的、規則的,還算好辦例如: li ...
  • 其實php開發中的中文編碼並沒有想像的那麼複雜,雖然定位和解決問題沒有定規,各種運行環境也各不盡然,但後面的原理是一樣的。瞭解字元集的知識是解決字元問題的基礎。 PHP程式設計中中文編碼問題曾經困擾很多人,導致這個問題的原因其實很簡單,每個國家(或區域)都規定了電腦信息交換用的字元編碼集,如美國的 ...
  • 一、重載(overload)指函數名相同,但是它的參數表列個數或順序,類型不同。但是不能靠返回類型來判斷。(1)相同的範圍(在同一個作用域中) ;(2)函數名字相同;(3)參數不同;(4)virtual 關鍵字可有可無。(5)返回值可以不同; 二、重寫(也稱為覆蓋 override)是指派生類重新定 ...
  • 1.什麼是JSP內置對象? jsp內置對象就是Web容器創建的一組對象,我們都知道Tomcat可以看成是一種Web容器,所以我們可以知道所謂的內置對象Tomcat創建的,使用內置對象時可以不適用new關鍵字, 直接使用即可. 2.什麼是內置對象? 解析:就是Web容器創建的一組對象,當Tocmat啟 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...