塊和函數式編程

編程範式有三種:過程式編程、面向對象編程和函數式編程。大部分現代編程語言並不能單純地歸爲某一範式。這些語言經常看起來屬於某種範式,同時又兼具其餘範式的特點。Objective-C主要是面向對象的,同時又經過塊借鑑了一些函數式的特性。程序員

函數式編程(Functional Programming,FP)web

塊:能夠把塊做爲參數傳遞,「複製」以備稍後使用,也能夠對其執行幾乎全部一般會用在基本數據類型上的操做。C程序員是用函數指針作這件事的。而塊區別於指針的一點是:塊能夠在其餘方法的詞法做用域中聲明,並且能夠在這個做用域中「捕獲變量的狀態」,不須要程序員作任何事塊就有上下文信息。編程

例子:展現一個UIAlertView,當用戶按下確認按鈕時執行一個動做。app

過程式方法:先建立一個UIAlertView對象,設置委託並實現回調,顯示UIAlertView,而後釋放。編程語言

- (IBAction) buttonTapped:(id) sender函數式編程

{函數

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"send email"spa

message:@"Are you sure you want to send is now?"指針

delegate:selform

cancelButtonTitle:@"Cancel"

otherButtonTitles:@"send",nil];

[alert show];

[alert release];;

}

-(void) alertView:(UIAlertView*) alertView didDismissWithButtonIndex:(NSInteger) buttonIndex

{

if(buttonIndex != [alertView cancelButtonIndex])

{

[self sendTheMail];

}

}

-(void) sendTheMail

{

//發送郵件的代碼

}

如今看看一個遵循函數式範式的UIAlertView的調用

[UIAlertView showAlertViewWithTitle:@"Send email"

message:@"Are you sure you want to send it now?"

cancelButtonTitle:@"Cancel"

otherButtonTitles:[NSArray arrayWithObjects:@"send",nil] 

onCompletion:^{

//發送郵件的代碼

}

onCancel:^{//其餘處理

}

];

函數式範式不須要實現委託,不須要分配和釋放對象,不須要明確地顯示警告對話框。

塊是一種比較特殊的Objective-C對象。跟傳統的對象不一樣的是,塊不是在堆上建立的。主要有兩個緣由,一是在棧上分配空間幾乎老是比在堆上快;二是出於訪問其餘局部變量的須要。當塊做爲參數傳遞給別的方法時,塊被複制,它會從棧移動到堆上。這就意味着默認狀況下塊不能修改上下文數據。可是也能夠修改局部變量,只是須要用__block來修飾聲明變量。這個修飾符是爲了命令編譯器當塊被複制時也把變量__block複製過去。

知道了塊的原理,如今就來實現塊。

(1)爲UIAlertView 添加類別,頭函數爲UIAlertView+Blocks.h

#import <Foundation/Foundation.h>

//用typedef定義DismissBlock和CancelBlock


typedef void (^DismissBlock)(int buttonIndex);
typedef void (^CancelBlock)();

@interface UIAlertView (Blocks) <UIAlertViewDelegate> 

//方法定義
+ (UIAlertView*) showAlertViewWithTitle:(NSString*) title                    
                                message:(NSString*) message 
                         cancelButtonTitle:(NSString*) cancelButtonTitle
                      otherButtonTitles:(NSArray*) otherButtons
                             onDismiss:(DismissBlock) dismissed                   
                               onCancel:(CancelBlock) cancelled;
@end

(2)實現UIAlertView+Blocks.m

#import "UIAlertView+Blocks.h"

//爲塊聲明靜態存儲空間
static DismissBlock _dismissBlock;
static CancelBlock _cancelBlock;

@implementation UIAlertView (Blocks)

//實現基於塊的方法
+ (UIAlertView*) showAlertViewWithTitle:(NSString*) title                    
                                message:(NSString*) message 
                      cancelButtonTitle:(NSString*) cancelButtonTitle
                      otherButtonTitles:(NSArray*) otherButtons
                             onDismiss:(DismissBlock) dismissed                   
                                 onCancel:(CancelBlock) cancelled {
  
  _cancelBlock  = [cancelled copy];
  
  _dismissBlock  = [dismissed copy];
  
  UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
                                                  message:message
                                                delegate:[self self]
                                        cancelButtonTitle:cancelButtonTitle
                                        otherButtonTitles:nil];
  
 for(NSString *buttonTitle in otherButtons)
    [alert addButtonWithTitle:buttonTitle];
  
  [alert show];
  return alert;
}

//處理UIAlertViewDelegate
+ (void)alertView:(UIAlertView*) alertView didDismissWithButtonIndex:(NSInteger) buttonIndex {
  
if(buttonIndex == [alertView cancelButtonIndex])
{
_cancelBlock();
}
  else
 {
    _dismissBlock(buttonIndex - 1); // cancel button is button 0
 }  
}
@end

(3)調用

      [UIAlertView showAlertViewWithTitle:@"Test" 
                              message:@"Hi there" 
                    cancelButtonTitle:@"Dismiss" 
                    otherButtonTitles:[NSArray arrayWithObject:@"OK"] 
                            onDismiss:^(int buttonIndex)  {
                             
                              NSLog(@"Button Dismissed");
                            }
                             onCancel:^ {}];

這個就跟Android中的回到函數相似了

相關文章
相關標籤/搜索