Block传值与协议传值的比较

来源:互联网 发布:易语言 tcp 发送数据 编辑:程序博客网 时间:2024/06/07 14:09
    /**
     block 三个过程
     1.声明block.         (声明协议)
     2.给block赋值         (签署协议)
     3.调用block           (代理调用协议)
     4.block体中具体实现    (代理方法的实现)
     

     */

第二个界面SecondView给View传值

1.先在SecondViewController.h中声明block

#import <UIKit/UIKit.h>@interface SecondViewController : UIViewController<span style="color:#FF0000;">@property (nonatomic , strong) void (^passValueBlock)(NSString *value);</span>//passValueBlock是这个block的名字@end

2.在SecondViewController.m中给block赋值
<span style="font-size:18px;">#import "SecondViewController.h"@interface SecondViewController ()@end@implementation SecondViewController- (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view.    UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];    [button setTitle:@"Send Message" forState:UIControlStateNormal];    button.frame = CGRectMake(100, 100, 100, 30);    [button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];    [self.view addSubview:button];}- (void)buttonClicked: (UIButton *)sender{    //调用代码块(也就是View里面跳过执行的block代码块);    <span style="color:#FF0000;">self.passValueBlock(@"happy new year again");</span>   }- (void)didReceiveMemoryWarning {    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated.}/*#pragma mark - Navigation// In a storyboard-based application, you will often want to do a little preparation before navigation- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {    // Get the new view controller using [segue destinationViewController].    // Pass the selected object to the new view controller.}*/@end</span>

3.在ViewController.m中包含SecondViewContoller.m获取block传过来的值

<span style="font-size:18px;">#import "ViewController.h"#import "Customimage.h"#import "SecondViewController.h"@interface ViewController ()<SecondViewControlerDelegate>@end@implementation ViewController{//    UIImageView *imageView;        /*        代码块,实际就是函数,但是它可以没有名字(匿名函数)。     */    //代码块的声明    int (^myBlock)(int);    UILabel *label;    BOOL isLager;    CGRect rect;}- (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view, typically from a nib.    //代码块的赋值    myBlock = ^(int a){        return a * 2;    };    //快速执行代码块    myBlock(5);    //    [self createUI];    [self createLabel];}- (void)createLabel{    label = [[UILabel alloc] initWithFrame:CGRectMake(100, 100,200, 44)];    label.layer.borderWidth = 1;    label.layer.borderColor = [UIColor yellowColor].CGColor;    [self.view addSubview:label];        UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];    [button setTitle:@"To Second" forState:UIControlStateNormal];    button.frame = CGRectMake(100, 300, 100, 30);    [button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];    [self.view addSubview:button];    }- (void) buttonClicked: (UIButton *)sender{    SecondViewController *SecondVC = [[SecondViewController alloc] init];    //代码块的赋值(内涵具体实现)。(遇到^跳过执行,等待SecondView中的调用执行)   <span style="color:#FF0000;"> SecondVC.passValueBlock = ^(NSString *value){        [self showMessage:value];    };</span>    [self presentViewController:SecondVC animated:YES completion:nil];}- (void) showMessage: (NSString *)message{    label.text = message;    [self dismissViewControllerAnimated:YES completion:nil];    }- (void)secondViewController:(SecondViewController *)controller passValue:(NSString *)value{        label.text = value;    [self dismissViewControllerAnimated:YES completion:nil];        }- (void)createUI{//    imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 50, 50)];//    imageView.backgroundColor = [UIColor yellowColor];//    [self.view addSubview:imageView];    Customimage *imageView = [[Customimage alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];    imageView.backgroundColor = [UIColor yellowColor];    imageView.action = @selector(handelImageTouch:);    imageView.target = self;    [self.view addSubview:imageView];    imageView.changeFrameBlock = ^(Customimage *imageView) {        [self handelImageTouch:imageView];    };    /**     block 三个过程     1.声明block.         (声明协议)     2.给block赋值         (签署协议)     3.调用block           (代理调用协议)     4.block体中具体实现    (代理方法的实现)          */}- (void)handelImageTouch: (Customimage *)image{    image.frame = self.view.frame;        //父视图把一张子视图放到最上面    [self.view bringSubviewToFront:image];                NSLog(@"papapapapapa");}//- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{//    NSLog(@"touchBegan...");//}//- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{//    NSLog(@"touchesEnd......");//}//- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{//    //触碰的对象//    UITouch *touch = [touches anyObject];//    //得到触碰到view的触碰点的坐标//    CGPoint point = [touch locationInView:self.view];//    //    imageView.center = point;//    NSLog(@"touchMoved........");//}- (void)didReceiveMemoryWarning {    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated.}@end</span>

在新浪blog上看到比较协议传值和block传值的区别

原blog出处 http://blog.sina.com.cn/s/blog_6317728d0102vcd6.html#cmt_3368157点击打开链接

除了代理传值的事件 ,还有一种可以更为简便的方法 ,就是block 传值,利用block 传值 在控制器跳转的瞬间将值传递。

例子:将Vc1 控制器接收传值 ,Vc2控制器发送传值消息,为了便于区别和代理传值的 使用 , 将两者放到一起其中Vc1控制器里 两个UITextField一个接收代理传值的使用,一个接收block 的使用 。
Vc1 :


#import"ViewController.h"

#import"SecondViewController.h"

@interfaceViewController()<</span>secondViewControllerDelegate>

- (IBAction)gengxin;

@property (weak,nonatomic)IBOutletUITextField*textField;

@property (weak,nonatomic)IBOutletUITextField*secTextField;

@property (nonatomic,strong)SecondViewController*secVc;

@end


@implementationViewController


- (void)viewDidLoad{

   [superviewDidLoad];

   // Do any additional setup after loadingthe view, typically from a nib.

   SecondViewController*secondVc= [[SecondViewControlleralloc]init];

    [secondVcreturnText:^(NSString*showText) {

      NSLog(@"---------%@------------",showText);

      self.secTextField.text= showText;

    }];

   self.secVc= secondVc;

  self.secVc.delegate=self;

    

}

- (IBAction)gengxin{

   [selfpresentViewController:self.secVcanimated:YEScompletion:nil];

}

#pragma mark - secondViewControllerDelegate

- (void)setTextfield:(NSString*)text{

   self.textField.text= text;

   NSLog(@"%@",text);

}

@end

Vc2 :

#import"ViewController.h"

@protocolsecondViewControllerDelegate

@optional- (void)setTextfield:(NSString*)text;

@end


typedefvoid(^returnBlock)(NSString*showText);

@interfaceSecondViewController :ViewController

@property (nonatomic,strong)iddelegate;

//声明block属性

@property (nonatomic,strong)returnBlockreturnTextBlock;

//声明调用方法

- (void)returnText: (returnBlock)block;

@end


 

#import"SecondViewController.h"


@interfaceSecondViewController()

@property (nonatomic,weak)UITextField*textField;

@property (nonatomic,weak)UIButton*saveButton;

@end


@implementationSecondViewController

 

- (void)viewDidLoad{

   [superviewDidLoad];

   // Do any additional setup after loadingthe view.

  self.view.backgroundColor=[UIColorgrayColor];

   UITextField*textField =[[UITextFieldalloc]init];

    [self.viewaddSubview:textField];

   [textField setBorderStyle:UITextBorderStyleRoundedRect];

   self.textField= textField;

   self.textField.frame=CGRectMake(100,100,100,100);

   UIButton*save = [[UIButtonalloc]init];

    [self.viewaddSubview:save];

   self.saveButton= save;

   self.saveButton.frame=CGRectMake(200,200,100,70);

   [self.saveButtonsetTitle:@"确定"forState:UIControlStateNormal];

  self.saveButton.titleLabel.textColor=[UIColorblackColor];

   [self.saveButtonaddTarget:selfaction:@selector(buttonClick:)forControlEvents:UIControlEventTouchUpInside];

    

}

- (void)buttonClick:(id)sender{

   if([self.delegaterespondsToSelector:@selector(setTextField:)]){

      NSString*text =self.textField.text;

       [self.delegatesetTextfield:text];

    }

   [selfdismissViewControllerAnimated:YEScompletion:nil];

}

- (void)didReceiveMemoryWarning{

   [superdidReceiveMemoryWarning];

   // Dispose of any resources that can berecreated.

    

}

- (void)returnText:(returnBlock)block

{

  self.returnTextBlock=block;

}

- (void)viewDidDisappear:(BOOL)animated

{

  //即将消失的时候

  if(self.returnTextBlock!=nil){

      self.returnTextBlock(self.textField.text);

    }

  NSLog(@"======%@=======",self.returnTextBlock);

}

 

@end


两者之间 的理解方式相同 ,在Vc1传值的里面,将returenText:方法 里的 block值传入vc2控制器里,在控制器Vc2跳转的时候 ,可以判断属性里有值 ,然后再重新加载vc1的时候就可以将值写入控制器里的secTextField里了。







0 0
原创粉丝点击