iOS的Block函数

一、什么是block(块)


笔者刚学习Block的时候也是很迷惑,到底什么是block,它封装了一段代码,这段代码可以在任何时候执行。block可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值。(也就是把所携带的参数一起,打包返回)它和传统的函数指针很类似。

二block的定义

(1)在类中,定义一个Block变量,就像定义一个函数;
(2)Block可以定义在方法内部,也可以定义在方法外部;
(3)只有调用Block时候,才会执行其{}体内的代码;

定义:
typedef 返回值类型(^BlockName)(参数列表)

实例:typedef void(^my_block_fun)(vid){
}

 // 声明和实现写在一起,就像变量的声明实现 int a = 10;
         int (^MyBlock1)(int, int) = ^(int num1, int num2) {

         return num1 * num2;

       };

  // 声明和实现分开,就像变量先声明后实现 int a;a = 10;
          int (^MyBlockk2)(int,int);
          MyBlock2 = ^(int num1,int num2)
         {
             return num1 * num2;
         };

分析:
 1、MyBlock1 有两个形式参数,分别为int类型;

 2、MyBlock2 的返回值为int 类型;

 3、等式右边就是blocks的具体实现;

 4、^ 带边blocks声明和实现的标示(关键字);

可以定义其他形式的block。无返回值,无形式参数等;
         //这样有等号=相当于  声明=实现 写在一起

         void (^MyBlock3)() = ^()
         {
             int a = 10;
             printf("num = %d",a);
         };  

分析:
 1、左边为声明 一个 返回类型 为空(void)函数名为 (^MyBlock3) 参数值为()没有定义 的block

 2、右边为实现MyBlock3这个函数

blocks 访问权限问题


  blocks可以访问局部变量,但是不能修改。

         int a = 10;
         int (^dBlock)(int) = ^(int num)
         {
             a++;//not work!
             return num * a;
         };

此处不能修改的原因是在编译期间确定的,编译器编译的时候把a的值复制到block作为一个新变量(假设是a‘ = 10),此时a’和a是没有关系的。
这个地方就是函数中的值传递。如果要修改就要加关键字:__block或者static

         __block int a = 7;
         int (^dBlock)(int) = ^(int num)
         {
             a++;// work!
            return num * a;
         };

三、Block的基本实现-传值


第一步

创建两个视图控制器,在Aview视图控制器中创建一个UILabel和一个UIButton,其中UILabel是为了显示Bview控制器传过来的字符串,UIButton是为了push到Bview。

第二步

Bview的只有一个UITextField,是为了输入文字,当输入文字,并且返回Aview,Bview消失的时候,Bview界面上TextFiled中的文字传给Aview,并且显示在UILabel上。

1、在Bview视图控制器的.h文件中定义声明Block属性

#import <UIKit/UIKit.h>
//定义block的名字
typedef void (^ReturnTextBlock)(NSString *showText);
@interface BView : UIViewController
//定义block的属性
@property (nonatomic, copy) ReturnTextBlock returnTextBlock;

@end

2、实现Bview控制器的方法

#import "BView.h"

@interface BView ()
//写在.h文件是  外部接口  写在.m文件中 是内部调用没有暴露接口 不想被外部调用就写在.m文件中
//创建用来输入的  UITextField
@property (nonatomic,weak) UITextField* inputTF;
@end

@implementation BView

- (void)viewWillDisappear:(BOOL)animated {
    //1.判断写入的值是否为空
    //2.不为空则实现把输入存到returnTextBlock
    if (self.returnTextBlock != nil) {
        self.returnTextBlock(self.inputTF.text);
    }
}

@end

实现Aview控制器的方法引用

    BViewController *BView=[[BViewController alloc]init];
    BView.returnTextBlock = ^(NSString *returnStr) {
        NSLog(@"%@",returnStr);
    };
    [self.navigationController pushViewController:BView animated:YES];

四、Block的用途

**假设A有一个任务,是去仓库取一张A4纸放到会议室,然后在纸上写一份策划书。取纸又要经过仓库管理员,于是A通知仓库管理员来张纸过来。由于管理员是个老头动作很慢,另外A还有其他工作,如果一直等待管理员就太浪费时间了,合理的做法是让仓库管理员进行取纸这项工作,A在通知管理员后就继续自己的工作。A不知道仓库管理员什么时候能完成取纸,也就不知道什么时候可以在纸上写策划书。这时block机制就派上用场了,使用这种机制,可以让A在通知仓库管理员取纸的同时,告诉仓库管理员将纸放到编号XX会议室,并安排好将要在纸上写的策划内容,当管理员把纸拿来后,可能过一会就会有个助理将策划内容写到纸上。假设我们熟悉代理递值的话,对代理我们可能又爱有恨!我们先建立模型A页面 push B页面,如果把A页面的值传递到B页面,属性和单例传值可以搞定!但是如果Pop过程中把B页面的值传递到A页面,那就可以用单例或者代理了!说到代理,我们要先声明协议,创建代理,很是麻烦。常常我们传递一个数值需要在两个页面间写很多代码,这些代码改变页面的整体顺序,可读性也打了折扣**
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值