您的位置:首页 > 编程语言

块和函数式编程(翻译+个人想法)

2013-07-12 13:54 253 查看
编程范式有三种:过程式编程、面向对象编程和函数式编程。大部分现代编程语言并不能单纯地归为某一范式。这些语言常常看起来属于某种范式,同时又兼具其他范式的特色。Objective-C主要是面向对象的,同时又通过块借鉴了一些函数式的特性。

函数式编程(Functional Programming,FP)

块:可以把块作为参数传递,“复制”以备稍后使用,也可以对其执行几乎所有通常会用在基本数据类型上的操作。C程序员是用函数指针做这件事的。而块区别于指针的一点是:块可以在其他方法的词法作用域中声明,而且可以在这个作用域中“捕获变量的状态”,不需要程序员做任何事块就有上下文信息。

例子:展示一个UIAlertView,当用户按下确认按钮时执行一个动作。

过程式方法:先创建一个UIAlertView对象,设置委托并实现回调,显示UIAlertView,然后释放。

- (IBAction) buttonTapped:(id) sender

{

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

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

delegate:self

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中的回到函数类似了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐