編程範式有三種:過程式編程、面向對象編程和函數式編程。大部分現代編程語言並不能單純地歸爲某一範式。這些語言經常看起來屬於某種範式,同時又兼具其餘範式的特點。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中的回到函數相似了