• Swift: 比较Swift中闭包传值、OC中的Block传值


    一、介绍

    开发者对匿名函数应该很清楚,其实它就是一个没有名字的函数或者方法,给人直观的感觉就是只能看到参数和返回值。在iOS开发中中,它又有自己的称呼,在OC中叫Block代码块,在Swift中叫闭包(Closure)函数。在我个人看来,两者并没有什么太大不同,定义和实现方式差不多,只不过是名称不一样罢了。由于开发用的比较多,所以我就针对OC和Swift分别写一下他们的传值方式,加深印象。

    二、需求

    定义两个控制器分别为FirstViewController和SecondViewController,在FirstViewController中定义闭包或者block,在Push到第二个控制器SecondViewController后,点击SecondViewController的屏幕触发闭包或者block,打印闭包或者block传递过来的值。

    三、步骤

    • 声明闭包或者block别名
    • 定义闭包或者block属性
    • 定义触发闭包的函数/方法
    • 定义传值的函数/方法

    四、测试

    1、Swift:闭包Closure

    FirstViewController.swift

    import UIKit
    
    /**
     *  声明一个闭包别名,闭包含字符串类型的两个参数,无返回值(使用“()”或者“Void”都一样)
     */
    typealias SwiftClosure = (name:String,age:Int) -> Void
    
    class FirstViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            self.view.backgroundColor = UIColor.whiteColor()
            
         //创建push按钮 let button
    = UIButton.init(frame: CGRectMake(200, 200, 100, 100)) button.setTitle("Push", forState: .Normal) button.center = self.view.center button.backgroundColor = UIColor.greenColor() button.setTitleColor(UIColor.redColor(), forState: .Normal) button.addTarget(self, action: #selector(PushSecondViewController), forControlEvents: .TouchUpInside) self.view.addSubview(button) } /** * 定义闭包属性,可选类型 */ var callBackClosure = SwiftClosure?() /** * 定义触发闭包调用的方法,此时需要将要传递的参数存入闭包中 * 此处我将参数固定死了,开发中根据需要自己可以将需要的数值当做方法的参数,其实就是给方法添加参数即可,由外部决定参数值 * 例如: func TriggerClosure(name:String,age:Int) -> Void { } */ func TriggerClosure(){ if callBackClosure != nil { callBackClosure!(name:"夏远全",age:26) } } /** * 闭包触发调用后,对闭包属性赋值,同时提供调用外部访问闭包中数值的接口 */ func callBackClosureFunction(closure:SwiftClosure){ callBackClosure = closure } /** * Push第二个控制器入栈 */ func PushSecondViewController() -> Void { self.navigationController?.pushViewController(SecondViewController(), animated: true) } }

    SecondViewController.swift

    import UIKit
    
    class SecondViewController: UIViewController {
    
        /**
         *  创建第一个控制器实例
         */
        let firstVC = FirstViewController()
        
        
        override func viewDidLoad() {
            super.viewDidLoad()
            self.view.backgroundColor = UIColor.purpleColor()
            
            /**
             * 接收闭包触发后回传的数值并打印
             */
            firstVC.callBackClosureFunction { (name, age) in
                print("name:(name), age:(age)")
            }
        }
        
        /**
         *  点击屏幕触发闭包
         */
        override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
            firstVC.TriggerClosure()
        }
        
    }

    点击演示结果如下,每一次点击都会触发闭包打印数据:

    name:夏远全, age:26
    name:夏远全, age:26
    name:夏远全, age:26
    name:夏远全, age:26
    ..................

    2、OC:Block代码块

    FirstViewController.h

    #import <UIKit/UIKit.h>
    
    /**
     *  声明一个block别名,block含字符串类型的两个参数,无返回值
     */
    typedef void (^OCBlock)(NSString *name,NSInteger age);
    
    @interface FirstViewController : UIViewController
    
    /**
     *  触发block
     */
    -(void)TriggerBlock;
    
    /**
     *  block回调
     */
    -(void)callBackBlockFunction:(OCBlock) block;
    
    @end

    FirstViewController.m

    #import "FirstViewController.h"
    #import "SecondViewController.h"
    
    
    
    @interface FirstViewController ()
    /**
     *  定义block属性
     */
    @property (copy,nonatomic)OCBlock callBackBlock;
    @end
    
    @implementation FirstViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
     
        //创建push按钮
        UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(200, 200, 100, 100)];
        [button setTitle:@"Push" forState:UIControlStateNormal];
        [button setTitleColor:[UIColor greenColor] forState:UIControlStateNormal];
        [button setBackgroundColor:[UIColor redColor]];
        [button addTarget:self action:@selector(PushSecondViewController) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:button];
    }
    
    /**
     *  Push第二个控制器入栈
     */
    -(void)PushSecondViewController{
        [self.navigationController pushViewController:[[SecondViewController alloc] init] animated:YES];
    }
    
    /**
     *  定义触发block调用的方法,此时需要将要传递的参数存入block中
     *  此处我将参数固定死了,开发中根据需要自己可以将需要的数值当做方法的参数,其实就是给方法添加参数即可,由外部决定参数值
     *  例如:-(void)TriggerBlock(name:String,age:Int) { }
     */
    -(void)TriggerBlock{
        
        if (self.callBackBlock) {
            self.callBackBlock(@"夏远全",26);
        }
    }
    
    /**
     *  block触发调用后,对block属性赋值,同时提供调用外部访问block中数值的接口
     */
    -(void)callBackBlockFunction:(OCBlock) block{
        self.callBackBlock = [block copy];
    }
    
    
    @end

    SecondViewController.m

    #import "SecondViewController.h"
    #import "FirstViewController.h"
    
    @interface SecondViewController ()
    /**
     *  创建第一个控制器实例
     */
    @property (strong,nonatomic)FirstViewController *firstVC;
    @end
    
    @implementation SecondViewController
    
    -(void)viewDidLoad{
        [super viewDidLoad];
        self.view.backgroundColor = [UIColor greenColor];
        
        
        _firstVC = [[FirstViewController alloc] init];
        
        /**
         * 接收block触发后回传的数值
         */
        [_firstVC callBackBlockFunction:^(NSString *name, NSInteger age) {
            NSLog(@"name:%@  age:%ld",name,age);
        }];
        
    }
    
    /**
     *  点击屏幕触发Block
     */
    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
        
        [_firstVC TriggerBlock];
    }
    
    @end

    点击演示结果如下,每一次点击都会触发闭包打印数据:

    2017-01-06 17:51:19.814 闭包[26322:355426] name:夏远全  age:26
    2017-01-06 17:51:27.837 闭包[26322:355426] name:夏远全  age:26
    2017-01-06 17:51:28.037 闭包[26322:355426] name:夏远全  age:26
    2017-01-06 17:51:28.221 闭包[26322:355426] name:夏远全  age:26
    2017-01-06 17:51:28.405 闭包[26322:355426] name:夏远全  age:26
    ..............................................

    本人原创,转载须注明出处,希望对大家有帮助,共同进步!!!

  • 相关阅读:
    leetcode ZigZag conversion(mediium) /java
    leetcode longest palindromic substring (medium) /java
    leetcode longest substring without repeating characters(medium) /java
    leetcode two_sum (easy) /java
    think_in_java_多态
    java复用类知识
    java找不到或无法加载主类
    java程序包不存在
    集合
    列表的增删改查
  • 原文地址:https://www.cnblogs.com/XYQ-208910/p/6257268.html
Copyright © 2020-2023  润新知