编程范式有三种:过程式编程、面向对象编程和函数式编程。大部分现代编程语言并不能单纯地归为某一范式。这些语言经常看起来属于某种范式,同时又兼具其余范式的特点。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中的回到函数相似了