块和函数式编程

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

相关文章
相关标签/搜索