IOS Block详解

iOS开发---Block详解 文章目录iOS开发---Block详解Block的基础什么是Blocks?Blocks的语法Block类型变量Block在oc中的使用Block截取变量截获自动变量的值通过__block说明符赋值Block的实现Block的实质是什么?准备工作Block源码预览Block结构体`struct __block_impl` 结构`static struct __main_block_desc_0`结构... 阅读详情


 这是我原先写的OC中关于协议和代理的文章,建议大家阅读此篇文章的时候先阅读此文章,便于大家理解:   IOS Protocol与Delegate详解(一)  IOS Protocol与Delegate详解(二)


 官方中对于Block的用途为: 


 You can use blocks to compose function expressions that can be passed to API, optionally stored, and usedby multiple threads. Blocks are particularly useful as a callback because the block carries both the code to beexecuted on callback and the data needed during that execution. 


  你可以使用Blocks组成方法表达式组成API接口,可选择的存储,或者运用其在不同的线程中,Blocks在回调中非常的重要因为Blocks携带了需要回调的代码和执行时的参数

 

   从上面可以看出,

   Blocks最最重要的地方就是可以用来回调,准确的是,是用来方便的回调

   如果你看过我以前写的"Protocol与Delegate详解"的话,就会知道,Protocol(协议)可以看成是一个方法的集合,而block可以看成只有一个方法的确定名称的Protocol(协议),

  也就是说,block可以说是一个不标准的协议,,类似于我们的口头协议

  但是,就是这么一个不标准的协议,却很大的方便了我们程序的开发,试想,如果我去路边的小摊买一个冰棍,难道我和摊主还要签订一个买卖协议?不会,至少我没有见到过

  如果真要通过协议的方法来实现上述交易过程的话其实也可以,即先定义一个买卖协议,其中有一个方法,传入值为金钱,返回值为商品对象,然后摊主实现此协议,我就可以调用摊主的这个协议中的方法,最后顺利吃上我的冰棍

  你也许会想,这也太麻烦了,简直就是反人类,所以,我们可以让摊主实现一个传入值为金钱,返回值为商品对象的block对象。然后我去调用这个对象即可。

  也就是说,我们定标准的时候不用在费尽的写一个协议,在让类实现这个协议,以后只需写一个blocks方法对象,然后直接调用即可


  说了这么多,可能你对blocks还不太理解,没事,我们先从基础讲起

 

  block的基础应用:

       ①.定义并使用blocks :

        You use the ^ operator to declare a block variable and to indicate the beginning of a block literal. The body of the block itself is contained within {}

        你可以使用^操作符来定义一个block变量,^操作符出现在block的开头。block的body在{}里面。

        示例:

        int multiplier = 7;
        int (^myBlock)(int) = ^(int num) {
        return num * multiplier;
        };

        //直接使用:

         printf("%d", myBlock(3));
         // prints "21"

        注意,这种使用方法是直接将myBlock当做一个指向普通方法的指针来使用的,你可能有疑惑,我只向myBlock传了一个参数3(即是blocks中的num参数)啊,multiplier在哪呢,multiplier在myBlock的上面。下面是API文档中的解释:

       Notice that the block is able to make use of variables from the same scope in which it was defined.

      所以myBlock可以直接使用multiplier变量

      下面是上述block的示例图:

   

     ②.直接使用blocks来进行回调 :

     上面定义并使用blocks的方法就不在多说了,在自己类中定义并使用blocks)不是经常被使用,我们使用blocks一般是用作回调

     使用我之前写的Delegate中的一个例子:  IOS Protocol与Delegate详解(二)   我们把里面的"小李买茶"的例子使用blocks来解决

     这是我们需要解决的问题: 

    比如说有一个领导,旁边有他的秘书小李,有一天,领导给小李说:"小李啊,没茶叶了,你给我买点上好茶叶去,如果买回来了,我就给你涨工资,如果没买上,就去站墙根去。"

    在上述问题中,小李需要有一个买茶叶的方法,但是买完茶叶回来呢?小李将茶叶买回来后的事件是领导来定义的,比如,"买回来了,我给你涨工资",这是领导制定的,小李只是执行这个方法罢了,

    所以,小李需要有三个方法,一个是成功的将茶叶买回来的事件方法,一个是没有吧茶叶买回来的事件方法,还有一个是自己买茶叶的方法,而这些事件方法,都可以直接写在买茶叶的方法中

    一般回调都是用于耗时操作,而耗时操作时候回调的方法一般都可以看做事件(Event)。例如在网上请求的耗时操作,成功后需要回调的请求成功事件(getSuccessEvent),有人讲义在Blcoks的引用的后面都加上Block,我不是很建议这样做。我建议在所有的回调事件的后面都加上Event,而不是Blcok,这样更易于自己和别人理解和维护

    下面上代码

      小李是Worker类的对象,其.m文件为;

  

#import "Worker.h"

@implementation Worker


/**
 
 去买茶叶的方法
 
 回调事件:
  
 buySuccessEvnet : 如果购买茶叶成功后会回调的事件
 
 buyFailEvnet    : 如果购买茶叶失败后回回调的事件
 
 */
-(void) buyTeaAndSetBuySuccessEvent:(void(^)()) buySuccessEvnet setBuyFailEvent:(void(^)()) buyFailEvnet{
    
    NSLog(@"正在买茶叶");
    
    //模拟买茶叶的耗时操作
    [NSThread sleepForTimeInterval : 3.0 ];
    
    NSLog(@"我买茶叶成功啦");
    
    //如果调用者实现了此blocks的话,则回调
    if (buySuccessEvnet) {
        
        buySuccessEvnet();
        
    }
    
}



@end

     .h文件为:

#import <Foundation/Foundation.h>

@interface Worker : NSObject{
    

}


/**
 
 去买茶叶的方法
 
 回调事件:
 
 buySuccessEvnet : 如果购买茶叶成功后会回调的事件
 
 buyFailEvnet    : 如果购买茶叶失败后回回调的事件
 
 */
-(void) buyTeaAndSetBuySuccessEvent:(void(^)()) buySuccessEvnet setBuyFailEvent:(void(^)()) buyFailEvnet;




@end


 我们就暂时不写领导的Leader类了,暂时将我们当做一个领导得意,直接在主方法中调用小李的方法

 下面是调用的方法(可以写在ViewController中的viewDidLoad方法里面):

- (void)viewDidLoad {
    [super viewDidLoad];
    
    
    Worker *xiaoLi = [[Worker alloc] init];
    
    //调用小李的买茶叶的方法
    [xiaoLi buyTeaAndSetBuySuccessEvent:^{
        
        NSLog(@"小李你做的不错,这月给你涨工资");
        
        
    } setBuyFailEvent:^{
        
        
         NSLog(@"小李你成天想什么呢,去墙角站着!");
        
    }];
    
    
}

执行后,输出的语句为:

  

正在买茶叶


三秒钟后,出现:

我买茶叶成功啦

小李你做的不错,这月给你涨工资


我们可以仔细分析一下上述代码,上述代码并没有在一个直接定义一个块变量,而是在方法中直接声明


这里有一个方面需要注意,即是如果这个方法是我的,我在这个方法里面声明了一个块,那我只需要调用即可(实际上这种调用即是回调)

而如果我调用了这个方法,这个方法需要传入块,那么我需要实现这个块,虽然这个块我没有定义变量,我只需要将这个块的body写上即可


这就是直接使用Block进行回调的例子,也是我们经常使用在项目中的Block的方法


   ③.定义并使用blocks来进行回调 :

   可能有人要问,既然我可以直接使用blocks来进行回调,那么我可以先定义一个blocks,然后在使用这个blocks进行回调吗,当然可以,但是非常不建议这样做,这样做的话有两个问题

  

   1.代码更多,不利用维护,理解

   2.可以会出现空指针的问题,即回调为空

 

   下面上这种方式写的代码:

   

   worker的.h文件:


#import <Foundation/Foundation.h>

@interface Worker : NSObject{
    

}



/**
 
 去买茶叶的方法

 */
-(void) buyTea;



//如果购买茶叶成功后会回调的事件
//记得要使用copy属性 参考: http://blog.sina.com.cn/s/blog_6dce99b10101bsum.html
@property (copy) void (^buySuccessEvnet)(void);

//如果购买茶叶成功后会回调的事件
@property (copy) void (^buyFailEvnet)(void);

@end


   .m文件:


#import "Worker.h"

@implementation Worker


/**
 
 去买茶叶的方法
 
 */
-(void) buyTea{
    
    NSLog(@"正在买茶叶");
    
    //模拟买茶叶的耗时操作
    [NSThread sleepForTimeInterval : 3.0 ];
    
    NSLog(@"我买茶叶成功啦");
    
    //如果调用者实现了此blocks的话,则回调
    if (self.buySuccessEvnet) {
        
        self.buySuccessEvnet();
        
    }
    
    
    
}



@end

  主方法中进行调用:

   Worker *xiaoLi = [[Worker alloc] init];
    
    //调用小李的买茶叶的方法
    [xiaoLi buyTea];

   不知道你发现了没有,这时候问题就出现了,因为没有设置xiaoLi的成功和失败事件,所以直接调用根本就实现不了。这样在团队合作中是一个很致命的问题,因为别人不是很清楚你写的Worker是怎么运作的,所以调用之前没有设置其blocks,所以会出现令别人困惑的问题。下面执行一下:

   

  只会出现这些结果:


  正在买茶叶


 我买茶叶成功啦


  正确调用的代码为:


 
    Worker *xiaoLi = [[Worker alloc] init];
    
    [xiaoLi setBuySuccessEvnet:^{
        
        NSLog(@"小李你做的不错,这月给你涨工资");
        
    }];
    
    [xiaoLi setBuyFailEvnet:^{
        NSLog(@"小李你成天想什么呢,去墙角站着!");
    }];
    
    
    //调用小李的买茶叶的方法
    [xiaoLi buyTea];


  则结果为:

  正在买茶叶 

  我买茶叶成功啦

 小李你做的不错,这月给你涨工资


 

  所以说,不是很建议使用这种方法,代码复杂且不够直接,很容易使用者感到困惑



  










  

       


       

         

  

 

玩转 IOS 开发 - block 使用详解 Block 是iOS在4.0之后新增的程式语法,在iOS SDK 4.0之后,block应用几乎无处不在。在其他语言中也有类似的概念称做闭包(closure),比如object C的好兄弟swift 中闭包(swift 闭包详解)的使用跟 OC的block一样重要。总的来说: Block是C语言的 Block是一个数据类型 Block 是一个提前准备好的代码,在需要的时候执行 1. 阅读详情

相关推荐

iOS block原理详解

block本质 block底层就是一个struct __main_block_impl_0类型的结构体,这个结构体中包含一个isa指针,本质上是一个OC对象 block是封装了函数调用以及函数调用环境的OC对象 block底层结构 block底层结构就是__main_block_impl_0结构体,内部包含了impl结构体和Desc结构体以及外部需要访问的变量,block将需要执行的代码放到一个函数里,impl内部的FuncPtr指向这个函数的地址,通过地址调用这个函数,就可以执行block里面.

gsl111000的博客 1397

iOS 关于Block代码块的详解

代码块Block是在iOS4开始引入的,是对C语言的扩展,用来实现匿名函数的特性 Block是一种特殊的数据类型,可以像基本数据类型一样定义成变量、作为参数、返回值来使用 Block还可以保存一段代码,在需要的时候调用

LOLITA0164的博客 1万+

Unity URP半透明物体深度排序优化:解决自交叠渲染瑕疵

本文深入探讨了Unity URP管线中半透明物体深度排序的优化方法,重点解决自交叠区域的渲染瑕疵问题。通过双通道渲染、深度预写入、多通道渲染等核心技术,结合实战案例和性能数据,帮助开发者实现高质量的透明效果渲染。

weixin_30879169的博客 418

IOS之Block详解

Block是iOS4.0+ 和Mac OS X 10.6+ 引进的对C语言的扩展,用来实现匿名函数的特性。block其实就是个必包函数,关于闭包,我觉得阮一峰的一句话解释简洁明了:闭包就是能够读取其它函数内部变量的函数,这个解释用到block来也很恰当:一个函数里定义了个block,这个block可以访问该函数的内部变量。 一个简单的Block示例如下: int (^maxBloc

liuzhiwei_051512的专栏 480

Stata实战入门:从数据导入到基础分析的全流程指南

本文提供了Stata实战入门的全流程指南,从数据导入、清洗到基础分析和可视化,帮助初学者快速掌握Stata的核心功能。通过详细的步骤和实用技巧,读者可以高效完成数据处理、变量操作、描述性统计和回归分析等任务,提升数据分析效率。

weixin_28327051的博客 383

学习记录(十一)--Pattern Recognition投稿记录

上一周特别忽然通知统计建模要答辩,确定是否晋级国赛,一直在准备答辩的事情,所以上一周没有总结周汇报,深刻检讨!!!不过结果是好的,我们组第二名晋级哦。这周主要是跟大家分享一下我投稿PR(Pattern Recognition)的一个时间线,以及投稿后的工作。一、PR从投稿到接收的时间线2025.4.3 Major Revision(ddl4.23) 当时正在弄比赛和另一个着急推进的文章2025.5.30 Minor Revision 这次小修基本上只有一些格式和简单一点点问题。

qq_54949944的博客 1917

iOS中Block完全详解

欢迎大家关注我的个人博客:https://darkknightkazuma.github.io #一、Block基础介绍 ##1、概念介绍 Block又称为块或块对象,它是苹果在OSX10.6和iOS4.0中新加入的功能,是C语言层面的特性及功能实现,类似其它语言的闭包(closure)功能.当时苹果正使用LLVM的clang作为C语言的编译器来改进C/OC/C++/OC++等的编译处理,Blo...

theShifter的博客 2658

Python小白也能玩转迅投QMT量化交易?手把手教你从安装到第一个策略

本文为零基础Python用户提供了上手迅投QMT量化交易平台的完整指南。从Python 3.6环境配置、QMT客户端获取安装,到核心概念讲解,并手把手教你编写并回测一个经典的双均线交易策略,帮助初学者快速迈出量化交易的第一步。

weixin_29103191的博客 763

iOS block详解

文章目录概述Block的定义与使用实际开发中的定义block与外界变量截获自动变量(局部变量)值默认情况__block修饰的外部变量Block的copy操作Block的存储域及copy操作__block变量与__forwarding防止Block循环引用Block的使用示例Block作为变量(Xcode快捷键:inlineBlock)Block作为属性(Xcode快捷键:typedefBlock)...

煮酒Shae 672

保姆级教程:用NFS把群晖NAS的文件夹挂到Ubuntu 22.04上,实现文件无缝共享

本文提供了一份详细的教程,指导用户如何通过NFS协议将群晖NAS的文件夹挂载到Ubuntu 22.04系统上,实现文件的无缝共享。文章对比了NFS与SMB协议的性能差异,并提供了群晖端和Ubuntu端的配置指南、高级参数优化、自动挂载方案以及生产环境中的实战技巧,帮助用户提升文件共享效率和系统稳定性。

weixin_29213827的博客 405

Android 11多窗口+分屏+APP窗口嵌套TaskView实现原理一

然而随着版本的迭代升级,google对分屏的定制差异化也越来越大,Androd 11的分屏用的是split-screen-primary和split-screen-secondary的方式,在systemui中去实现的,其定制化的灵活度不是很高,很多业务都是放到sustemui或者fw去实现,但是随着版本的升高,后面出现了TaskView来替代了老版本的分屏方式,但是Task的核心原理其实和之前的方式是一样的,TaskView来实现分屏。

qq_18420641的博客 2614

ios Block详解

一. iOS代码块Block 1.1 概述 代码块Block是苹果在iOS4开始引入的对C语言的扩展,用来实现匿名函数的特性,Block是一种特殊的数据类型,其可以正常定义变量、作为参数、作为返回值,特殊地,Block还可以保存一段代码,在需要的时候调用,目前Block已经广泛应用于iOS开发中,常用于GCD、动画、排序及各类回调 注: Block的声明与赋值只是保存了一段代码段,必...

weixin_30248399的博客 200

【目标跟踪】多目标跟踪的评价工具motmetrics怎么使用?

多目标跟踪,通过motmetrics测试评价对应的视频。

聿默的博客 5368

iOS开发——Block详解

iOS开发——Block详解 1. Block是什么 代码块 匿名函数 闭包——能够读取其他函数内部变量的函数 函数变量 实现基于指针和函数指针 实现回调的机制 Block是一个非常有特色的语法,它可以把一个代码块作为一个变量来保存,也可以通过函数传递变量,然后让其他的对象来执行这一代码块。可以保存传递并在其他地方执行的代码块,这是我对Block的理解,也是我觉得Block最吸引我...

anji4406的博客 149

PyTorch 面试题及参考答案(精选100道)

模块是 PyTorch 中用于自动求导的核心模块。它为张量上的所有操作提供了自动求导的功能。在深度学习中,反向传播是一种用于计算损失函数相对于模型参数的梯度的算法。通过梯度,我们可以使用优化算法(如随机梯度下降)来更新模型的参数,从而最小化损失函数。模块的主要作用就是自动计算这些梯度。当我们创建一个张量时,如果将其属性设置为True,那么 PyTorch 会跟踪该张量上的所有操作。在完成前向传播计算出损失函数后,调用方法,模块会自动根据链式法则反向传播计算出所有需要求导的张量的梯度。

大模型大数据攻城狮的专栏 1680

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

iOS block详解

本文大纲: 1、block基础语法 2、block基础使用 3、block常见问题 4、block进阶:深入代码理解 block基础语法: block作为c语言的扩展,正在oc中发挥着举足轻重的作用,我们经常食用block作为回调函数,这样做可以大大简化编程方式,多线程的核心也是block,因此,学会使...

198

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

iOS开发之block详解

iOS开发之block详解今天研究了一下iOS开发中的block,有些心得,故写下来。默认读者会是有[iOS开发经验的][6],故相关内容不再科普。 block的粗浅认识 block访问局部变量1 block访问局部变量2 LaTex数学公式 UML序列图和流程图 离线写博客 导入导出Markdown文件 丰富的快捷键 1.block入门[老子][6]说:学习编程,从翻译开始。block的翻译是什么

lq5672的博客 601

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

iOS的Block详解

Block是带有自动变量的匿名函数,是C语言的一个扩充功能。Block本质上也是一个OC对象,内部也有一个isa指针,其内部封装了函数调用以及函数调用环境。 (一)Block的基本使用 1. block声明 //返回值(^block变量名)(参数) void(^block)(); 2. block定义 //三种方式 = ^(参数){}; // 第一种:没返回值,没参数...

weixin_42433480的博客 1115

iOS block本质详解(二)

这篇文章主要的讲的是这三个方面。 * block捕获对象变量的本质 * __weak 修饰符 详解 * __block 修饰符 详解 * block 内存管理 详解 * block 循环引用 详解 block捕获对象变量的本质 在平时的开发中经常遇到block块里面,引用其他对象的代码,例如: typedef void (^Block)(void); int main(int argc, cons...

muziyuting的博客 392

iOS 开发 block深入浅出详解

block的定义与使用/* *1.最简单的定义方式: *格式:void (^myBlock)() = ^ { // 代码实现; } */ void (^myBlock)() = ^ { NSLog(@"hello"); };// 执行时,把block当成函数 myBlock();/* *2.定义带参数的block: *格式:void (^block名称)(参数列表) = ^ (参数列表) {

高级软件开发工程师--周玉的博客 576

iOS 之Block详解

Block可以帮助我们组织独立的代码段,并提高复用性和可读性。iOS4在UIKit中引入了该特征。超过100个的Apple API都使用了Block,所以这是一个我们必须开始熟悉的知识。 Block是什么样的?  你可以使用^操作符来声明一个Block变量,它表示一个Block的开始。 int num1 = 7; int(^aBlock)(int) = ^)int num2) {

Shicuf的专栏 398

iOS:Block详解

一 、 (一)定义和使用Block 首先使用^运算子来定义一个block变数,而且在block的定义后面加上; 来表示一个完整的述句int multiplier = 7 ;      int (^myBlock)( int ) = ^( int num)      {          return num * multiplier;      }; 我们定义一个「myBloc

小凡 ‘ Small growth 947

iOS中的block详解

1.block的写法 returnType(^blockName)(parameterTypes) = ^(parameters) { statements }; returnType 返回值类型,可以为void,不能为空 blockName 名称 parameterTypes 参数类型,可以为void或空 parameters 形式参数,可以为void或空 ...

孤独流浪的博客 868

iOS Block 详解

一、概述闭包 = 一个函数「或指向函数的指针」+ 该函数执行的外部的上下文变量「也就是自由变量」;Block 是 Objective-C 对于闭包的实现。其中,Block:可以嵌套定义,定义 Block 方法和定义函数方法相似Block 可以定义在方法内部或外部只有调用 Block 时候,才会执行其{}体内的代码本质是对象,使代码高聚合 使用 clang 将 OC 代码转换为 C++ 文件查看 b...

majiakun1的专栏 369

ios 添加block 类别_iOS 关于Block代码块的详解

概述block上图就是一个block简单使用,它包括了block的声明、赋值实现、调用 三个部分,其中,实现部分可以看作是一种匿名函数;跟函数一样,block也是需要调用才能执行内部代码的;赋值的行为又让block看起来跟数据类型类似代码块Block是在iOS4开始引入的,是对C语言的扩展,用来实现匿名函数的特性Block是一种特殊的数据类型,可以像基本数据类型一样定义成变量、作为参数、返回值来使...

weixin_39612677的博客 197
上一篇: parseSdkContent failedCould not initialize class android.graphics 的解决方法
下一篇: IOS TableView详解(一)
舞动的钢琴
博客等级 码龄12年 11粉丝 19原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值