iOS Block 详解(Object-C)

Block 是苹果公司较晚推出的一个语法,与很多语法的闭包差不多意思

一:Block声明

PS:很多人学不好Block,大概率是被它的声明写法给吓到了,写法确实有点奇怪

objectivec 复制代码
返回值类型(^block变量名)(参数列表)

例如: int(^personBlock)(NSString *,int)

objectivec 复制代码
返回值类型(^block变量名)(参数列表)

int(^personBlock)(NSString *,int)

返回值类型:int
block变量名: personBlock
参数列表:NSString *,int 
(注意:参数列表只需要写参数类型,不需要写参数名,例如:NSString * name 的写法是不对的,不需要写参数名name)

这句代码的意思是:声明了一个类型为Block,名字叫 personBlock 的变量, 这个变量有返回值,返回值的类型为int,同时它还可以接受参数,参数为NSString * , int

如何还不理解上面的那段话,可以配合下面两段理解

int age; 声明了一个 类型为 int,名字叫age 的变量 (不同的是,它没有返回值)

NSString * name; 声明了一个类型为NSString,名字叫叫name的变量 (不同的是,它没有返回值)

明白了上面的声明写法,那么Block的声明就可以随意发挥了,例如:

objectivec 复制代码
  //声明一个空返回值,没有参数的block
   void (^aBlock)(void) 

   //声明一个空返回值,参数有NSString *,NSString *,NSString *,int 的block
   void(^bBlock)(NSString *,NSString *,NSString *,int);
    
   //声明一个返回类型为NSString,参数有int 的block
   NSString* (^cBlock)(int) 

二:Block的定义+实现

上面讲了Block的声明,接下来定义:

objectivec 复制代码
返回值类型(^block变量名)(参数列表) = ^(参数列表) {

};

上Block的声明写到"=" 前面的"参数列表"只需要写参数类型,不需要写参数名.

"="后面的 "参数列表" 则需要写参数类型+参数名,例如:

objectivec 复制代码
- (void)viewDidLoad 
{
    [super viewDidLoad];
    

NSString * (^personBlock)(NSString *,int) = ^(NSString * name, int age){
        
        NSLog(@"年龄==%d",age);
        
        return name;
    };
    
    //实现
    NSString * name = personBlock(@"zhangsan",29);
    
    NSLog(@"姓名==%@",name);

}

定义了一个返回类型为NSString,参数类型为NSString *,int 的 block,

实现的时候跟实现方法调用一样

Block的声明+定义+实现 补充

常用的Block是用别名 typedef 的方式声明,与 @property 声明变量的方式差不多,例如:

objectivec 复制代码
#import "ViewController.h"

//使用别名的方式声明一个block
typedef void(^ PersonBlock) (int,NSString *);

@interface ViewController ()


@end

使用: 和结构题的使用方法差不多

objectivec 复制代码
- (void)viewDidLoad 
{
    [super viewDidLoad];
  
      PersonBlock pblock = ^(int age,NSString * name) {
        NSLog(@"年龄==%d,姓名==%@",age,name);
    };
    
    pblock(10,@"lisi");

}

三:Block的对变量的使用

Block可以对外部的变量进行使用,

objectivec 复制代码
- (void)viewDidLoad 
{
   
    [super viewDidLoad];

    int c = 20;
    
    int(^myBlock)(int,int) = ^(int a,int b ){
        
        //可以使用外部的c,例如:打印c,使用
        NSLog(@"c==%d",c);
        //又或者拿来做算术
        int d = a + b + c;
        
        return a+b;
    };
}

但是不能改变,如果非要改变,那么就需要在被改变的参数前加 __block.

在定义C的时候,在其前面加上__block 即可,例如:

objectivec 复制代码
    __block int c = 20;
    
    int(^myBlock)(int,int) = ^(int a,int b ){
        
        //如果不对c做处理,直接改变,则会报错
        c = 30;
        
        return a+b;
    };

四:Block使用场景

4.1.用作参数

4.2.用作返回值

彩蛋:xcode 为 block创建了一个代码块快捷键:在xcode上输入 inline,按回车,一个block的框架就出来了:

相关推荐
半摆烂日常1 分钟前
手机表单的左滑操作:触摸事件的处理细节
大数据·开发语言·人工智能·智能手机·https·c#
星夜离尘5612 分钟前
MATLAB滑动RMS如何接报警:窗口未满和缺样不能当成正常
开发语言·matlab
开开心心就好19 分钟前
白天晚上自动调蓝光,护眼工具亮度可调
服务器·开发语言·算法·pdf·ocr·intellij-idea·idea
张张123y20 分钟前
后端第十一课:RAG 落地实战(从 0 到 1 接上私有知识库,并设计一个好用的 RAG)
开发语言·人工智能·python·机器学习·fastapi·rag
梅梅绵绵冰22 分钟前
JVM虚拟机
java·开发语言·jvm
Shaoshing1 小时前
消息顺序
java·开发语言
云水初1 小时前
【项目篇】基于LanGraph的自动处理客服邮件的 Agent汇总
开发语言·笔记·python·学习·fastapi·langgraph
茉莉玫瑰花茶1 小时前
GO [ 内存与变量逃逸分析 ]
开发语言·后端·golang
我叫洋洋1 小时前
Cadence 16.6 从 OrCAD Capture 原理图到 Allegro PCB 全流程(含 5 个常见坑)
c语言·eda·嘉立创
lhh_qrsly1 小时前
OTA 加密完整方案(嵌入式 IoT 常用)
开发语言·物联网·php