扣丁書屋

簡述iOS開發中常用的編程思想

寫在最前

編程思想是一個宏觀的概念,在不同的計算機系統或者不同編程語言中可能有不同的定義和具體描述,就像我們經常會發現各種介紹編程思想的教材,如《C++編程思想》、《JAVA編程思想》等,在此我們不妨先給出一個較為宏觀的描述:通過計算機語言讓計算機解決人們的實際問題的思維方式,即編程思想。

在我們的日常開發項目之前,首先會站在全局的角度去思考我們最終要實現的目標,然后會對目標進行拆解,逐個部分進行實現,在實現過程中,我們需要遵守某一特性的準則,同時依賴準則的規范,這樣我們最終完成的各個部分功能才能完美的組合到一起,我們的最終的目標才能實現。這個過程中各種準則既是我們的編程思想。

隨著計算機技術的發展和軟件開發技術的發展,為了解決各種實際問題人們已經摸索總結出各種較為經典的編程思想,比如OOP(Object Oriented Programming)面向對象編程,AOP(Aspect Oriented Programming)面向切面編程,PO(Procedure Oriented)面向過程編程,FP(functional programming)函數式編程,RP(reactive programming)響應式編程, 鏈式編程等等。

OC中常用或者常見的編程思想

本文我們主要介紹在OC中我們經常使用或者經常見到的幾種編程思想,其中重點介紹一下OC中的鏈式編程、響應式編程和函數式編程,希望通過本文的介紹能幫助大家更好的規劃項目架構,提供更多的問題解決方案,和寫出更優雅的代碼。

01 鏈式

首先我們通過一個三方框架來看一個鏈式編程思想的使用方式和特性:


[self.view addSubView:_testView];

[_testView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.height.equalTo(15).width.equalTo(15);
}];

相信大家對這段代碼都很熟悉,是的這是我們常用的三方布局框架Masonry,在使用的過程我們對

make.height.equalTo(15).width.equalTo(15);

這種通過點(.)將對象和方法連接起來的代碼書寫方法充滿好奇,其實這種編程方式就是鏈式編程思想的體現。

make.height從我們的對OC語言的語法理解上我們可以知道height是一個get方法,我們可以看下在Masnory中height方法做了哪些事情:

// MASConstraintMaker.m
- (MASConstraint *)height {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeHeight];
}

- (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {
    return [self constraint:nil addConstraintWithLayoutAttribute:layoutAttribute];
}

- (MASConstraint *)constraint:(MASConstraint *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {

    MASViewConstraint *newConstraint = [[MASViewConstraint alloc] initWithFirstViewAttribute:viewAttribute];
    、、、
    return newConstraint;
}

從上面的代碼可以看出,get方法height返回了一個對象(MASViewConstraint),所以我們不難理解為什么get方法height后面我們可以繼續使用.語法,繼續往后看,那么equalTo是否也是make的一個get方法呢,但是不同于left方法,后面還有一個()可供我們提供入參,熟悉C++語言的朋友可能可以想到offset方法的返回值是一個函數指針,但是通過函數指針我們無法保證調用該方法對象和返回的對象是同一個,所以就無法繼續執行后面的點語法了,我們看下Masnory框架中是如何實現的:


- (MASConstraint * (^)(id))equalTo {
    return ^id(id attribute) {
        return self.equalToWithRelation(attribute, NSLayoutRelationEqual);
    };
}

return ^id(id attribute, NSLayoutRelation relation) {
        、、、
        return self;
    };

通過上面的代碼可以知道equalTo方法返回是一個MASConstraint * (^)(id)類型的block,而且這個block返回的是一個MASConstraint(MASViewConstraint的父類)類對象,equalToWithRelation方法返回了對象本身,所以我們繼續在equalTo方法之后使用.語法。

通過上面的代碼分析我們可以知道,如果想在OC中使用鏈式編程的思想,使用.語法后的方法必須返回一個對象,如果想對同一個對象通過.語法完成連續的方法調用,可以通過block實現,block返回實例本身。

鏈式編程的優點是可以按照功能和順序組織代碼,流程邏輯清晰,代碼簡潔,可讀性高。

02 響應式

響應式編程提高了代碼的抽象層級,所以你可以只關注定義了業務邏輯的那些相互依賴的事件,而非糾纏于大量的實現細節。響應式編程的代碼往往會更加簡明,比如我們在解決MVC架構中視圖控制器的邏輯代碼冗余、代碼量大的問題時,可以考慮MVVM架構,當我們使用MVVM架構的時候,大部分邏輯代碼會放到Viewmodel中,而VC中主要負責View視圖的管理,這是我們就需要Viewmode和VC間有一條數據通道,VC可以時刻知道Viewmode中的邏輯處理結果以決定如何現實自己管理的視圖,這時響應式編程就是一種很好的選擇。

在OC中我們經常用到響應式編程,如通知(NSNotificationCenter)、代理(delegate), KVO,我們通過下面一段KVO代碼來直觀的看下響應式編程的特點。

@interface ViewController ()
@property(nonatomic, strong) UILable *showLabel;
@property(nonatomic, strong) TestViewModel *viewModel;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //將本對象作為viewmode的監聽這
    [self.viewModel addObserver:self forKeyPath:"num" options:NSKeyValueObservingOptionOld context:nil];
}
//一旦viewmode的num屬性發生變化,就會通知本對象調用此方法,可在此方法內部做一些UI相關操作
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    self.showLabel.text = [change valueForKey:@"new"];
}
@end

在開發有著大量與數據事件相關的 UI events 的高互動性 Webapps、手機 apps 的時候,響應式編程 的優勢就更加明顯。10年前,網頁的交互就只是提交一個很長的表單到后端,而在前端只產生簡單的渲染。Apps 就表現得更加的實時了:修改一個表單域就能自動地把修改后的值保存到后端,為一些內容"點贊"時,會實時的反應到其它在線用戶那里等等,現在的 Apps 有著大量各種各樣的實時 Events,以給用戶提供一個交互性較高的體驗。我們需要工具去應對這個變化,而響應式編程就是一個答案。

總結起來,響應式編程(reactive programming)是一種基于數據流(data stream)和變化傳遞(propagation of change)的編程思想,優點是在編程過程中不在需要考慮調用順序,只需要考慮結果即可,簡化邏輯。

03 函數式

主要思想是把運算過程盡量寫成一系列嵌套的函數調用。函數式編程是以函數為核心來組織模塊的一套編程方法。

函數式編程的特點:

  • 函數是"第一等公民";指的是函數與其他數據類型一樣,處于平等地位,可以賦值給其他變量,也可以作為參數,傳入另一個函數,或者作為別的函數的返回值。
  • 只用"表達式",不用"語句";"表達式"(expression)是一個單純的運算過程,總是有返回值;"語句"(statement)是執行某種操作,沒有返回值。函數式編程要求,只使用表達式,不使用語句。也就是說,每一步都是單純的運算,而且都有返回值。
  • 不修改狀態;函數式編程只是返回新的值,不修改系統變量。
  • 引用透明性;函數程序通常還加強引用透明性,即如果提供同樣的輸入,那么函數總是返回同樣的結果。就是說,表達式的值不依賴于可以改變值的全局狀態。

結合以上函數式編程的特點,我們在OC中實現一段函數式編程的代碼:

@interface CaculateManager : NSObject

@property(nonatomic, assign) NSInteger result;
//以一個block作為函數入參,體現“函數是一等公民的特征”
- (instancetype)caculate:(int (^)(int))caculateBlock;

@end

@implementation CaculateManager

- (instancetype)caculate:(int (^)(int))caculateBlock {
    _result = caculateBlock(_result);
    //此處增加一個對象自身的返回值,配合鏈式編程的思想,使調用更加簡潔
    return self;
}

@end
int main(int argc, char * argv[]) {
    @autoreleasepool {

        CaculateManager *caculateM = [CaculateManager new];
        //傳入一個block(函數)作為入參
        NSInteger result = [caculateM caculate:^int(int result) {
          //每一步都是單純的運算,而且都有返回值
            result +=100;
            return result;
        }].result; //.result使用的鏈式編程的思想,因為caculate函數返回了對象本身
    }
}

以上代碼是我們使用OC寫的一個函數式編程的代碼,可以發現我們上文中提到的Masnory框架的使用中也存在函數式編程的思想,代碼如下:

[containerView mas_makeConstraints:^(MASConstraintMaker *make) {
        、、、
}];
- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *))block {
      、、、
      block(constraintMaker);
      return [constraintMaker install];
}

由上面的示例代碼我們可以簡單總結下函數式編程的優點:

  • 代碼簡潔,開發快速;函數式編程大量使用函數,減少了代碼的重復,因此程序比較短,開發速度較快。
  • 接近自然語言,易于理解;函數式編程的自由度很高,可以寫出很接近自然語言的代碼。
  • 更方便的代碼管理;函數式編程不依賴、也不會改變外界的狀態,只要給定輸入參數,返回的結果必定相同。
  • 易于"并發編程";函數式編程不需要考慮"死鎖"(deadlock),因為它不修改變量,所以根本不存在"鎖"線程的問題。
  • 代碼的熱升級;函數式編程沒有副作用,只要保證接口不變,內部實現是外部無關的。

04 面向過程

面向過程編程思想想必大家再熟悉不過,比如大多數軟件開發者的啟蒙編程語言----C語言,采用的都是面向過程的編程思想。

總的來說,在面向過程編程中,問題被看成過程的有序組合,例如讀、計算、展示結果等等過程。以面向過程來思考為例,首先把問題分解成一系列過程,每個過程可以對應一個或者多個函數,實現所有的函數,問題就被解決了。在此我們不列舉代碼示例,只做一個簡單概念描述。

05 面向對象

OC本身就是一門面向對象的編程語言,所以對面向對象編程思想再熟悉不過,我們項目中有無數個對象,每一個對象都是我們抽象出來對應具體事物的且包含事物的特征。

面向對象編程以對象為核心,程序由一系列對象組成。類是對現實世界的抽象,包括表示靜態屬性的數據和對數據的操作,對象是類的實例化。對象間通過消息傳遞相互通信,來模擬現實世界中不同實體間的聯系。在面向對象的程序設計中,對象是組成程序的基本模塊。

寫在最后

編程的目的就是希望計算機解決我們現實生活中遇到的各種問題。編程思想是幫助我們寫出一套可維護性高,擴展性高的代碼的一套思想規范或者說工具,編程思想的本質是降低系統復雜度,減少重復,減少代碼的變更的。掌握了這個大方向,理解各種編程思想就容易多了。本文主要參考了百度百科中關于編程思想的一些定義就OC語言中一些開發中常見的編程思想做了一個簡單介紹,希望能幫助大家更好的理解編程思想,如有不準確的地方,敬請指正。


https://mp.weixin.qq.com/s/KxGc4du8raQtg0yzUDXfMQ

最多閱讀

iOS 性能檢測新方式?——AnimationHitches 7月以前  |  17284次閱讀
快速配置 Sign In with Apple 2年以前  |  5471次閱讀
APP適配iOS11 3年以前  |  4428次閱讀
App Store 審核指南[2017年最新版本] 3年以前  |  4256次閱讀
所有iPhone設備尺寸匯總 3年以前  |  4178次閱讀
使用 GPUImage 實現一個簡單相機 3年以前  |  3910次閱讀
開篇 關于iOS越獄開發 3年以前  |  3790次閱讀
在越獄的iPhone設置上使用lldb調試 3年以前  |  3715次閱讀
給數組NSMutableArray排序 3年以前  |  3639次閱讀
UITableViewCell高亮效果實現 3年以前  |  3344次閱讀
使用ssh訪問越獄iPhone的兩種方式 3年以前  |  3344次閱讀
關于Xcode不能打印崩潰日志 3年以前  |  3240次閱讀
使用ssh 訪問越獄iPhone的兩種方式 3年以前  |  3080次閱讀
為對象添加一個釋放時觸發的block 3年以前  |  2854次閱讀
使用最高權限操作iPhone手機 3年以前  |  2826次閱讀

手機掃碼閱讀
18禁止午夜福利体验区,人与动人物xxxx毛片人与狍,色男人窝网站聚色窝
<蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <文本链> <文本链> <文本链> <文本链> <文本链> <文本链>