IOS Block 代码块使用 (二)

iOS开发Delegate,Notification,Block使用心得 iOS开发Delegate,Notification,Block使用心得(一)简要介绍 1.Delegate(代理、委托) 代理几乎是iOS开发中最常用的传值方式,在项目中的AppDelegate就是使用的这种设计模式,不仅如此,还有很多原生的控件也使用的这种设计模式,比如:UITextFiled,UITableView等等。官方给出的解释如下: Delegation is a simple 阅读详情
 最近看了松本行弘(日)编写的代码的未来这本书,其中有一个章节详细介绍了有关函数闭包的内容,后来联想到IOS中的代码块(Block),其实它就是对闭包的一种实现。
    
      那么究竟什么是函数的闭包呢?

一 函数对象    

      在一些编程语言中提供了函数对象的概念,有些人也将其叫做闭包(Closure),但其实函数对象不一定是闭包。所谓函数对象,顾名思义,就是将对象当做函数来使用。不过这里的对象不一定是面向对象中所指的那个对象,而更像是编程语言所操作的数据这个意思。(有关面向对象中函数对象的概念见下面的补充说明)。

例如在C 语言中,我们可以获取一个函数的指针,并通过指针间接调用该函数。这就是C语言概念中的对象。如下面代码所示:

void HelloWorld(NSString* hello)
{
    
NSLog(@"Hello World!");
}
void HelloHadoop(NSString *hadoop)
{
    
NSLog(@"Hello Hadoop!");
}

int main(int argc, const char * argv[])
{
    
    
@autoreleasepool {
        
        
void (*FuncPointer)(NSString *args) = NULL;
        
        FuncPointer = 
HelloWorld;
        FuncPointer(
@"Hello World");
        
        FuncPointer = 
HelloHadoop;
        FuncPointer(
@"Hello Hadoop");
        
    }
    
return 0;
}

     FuncPointer是一个指向拥有一个NSString形式参数,返回值是void函数指针,而函数HelloWorld和HelloHadoop都满足以上的要求,可以被FuncPointer指针调用。

      函数对象,也就是将函数作为值来进行利用的方法,函数对象对我们编程来说有什么用呢?最大的用途就是高阶函数,就是用函数作为参数的函数。

二 用函数参数提高通用性

        在C语言标准函数库中,提供了一个通用性的排序函数,它的名字是qsort,函数原型为:
 
void qort(void *base,size_t nmemb,size_t size,int (*compar)(const void *,const void *)

      第一个参数表示待排序数组的首地址,第二个参数表示数据元素的个数,第三个参数表示数组元素大小,关键是第四个参数为一个函数指针可以传入任意类型的两种元素的比较,当两个元素相等时返回0,a>b返回正整数,否则返回负数。
       qsort函数是通过将另外一个函数作为参数使用,来实现通用排序功能。高阶函数这样的方式,通过将一部分处理以函数的形式转移到外部,从而实现了算法的通用化。


三 函数指针的局限

请细细分析下面的这段代码:
  
#include <stdio.h>
#include <stdlib.h>

struct node {
   
 struct node *next;
   
 int val;
};   /*结构体的定义*/

typedef void(*func_t) (int); /*函数指针类型*/

void foreach(struct node *list,func_t func)
{
   
 while (list != NULL) {
        func(list->
val);
        list = list->
next;
    }
}
void f(int n)
{
   
 printf("node(?) = %d\n",n);
}
int main(int argc, const char * argv[])
{

   
 @autoreleasepool {
       
       
 struct node *list = NULL,*l;
       
       
 for(int i=0;i<4;++i)
        {
            l =
 malloc(sizeof(struct node));
            l->
val = i;
            l->
next = list;
            list = l;
        }
       
       
 int i = 0;
        l=list;
       
       
 while (l != NULL)
        {
           
 printf("node(%d) = %d\n",i++,l->val);
            l = l->
next
;
        }
       

       
 foreach(list, f);
       
    }
    return 0;
}

输出结构:

node(0) = 3
node(1) = 2
node(2) = 1
node(3) = 0
node(?) = 3
node(?) = 2
node(?) = 1


分析:函数指针的局限性主要体现在下面的两个方面:
   1.foreach函数的第二个参数所指向的函数必须在远离循环体的地方单独进行定义,这是C语言函数指针的第一个缺点,在大多数语言中,函数都可以在需要调用的地方当场定义,这个是C语言所固有的缺点。
   2.从运行结果看在,与while语句不同,foreach的循环实际是在另一个函数中执行的,因此无法从函数中访问位于外部的局部变量i.

       函数对象与函数指针相比较有两个方面的优点:首先如果被重载的调用操作符是inline函数则编译器能够执行内联编译,提供可能的性能好处;其次函数对象可以拥有任意数目的额外数据,用这些数据可以缓冲结果,也可以缓冲有助于当前操作的数据。

四 闭包

首先看下面的代码:

#include <stdio.h>
#include
 <stdlib.h>

struct node {
   
 struct node *next;
   
 int val;
};
typedef void(^func_t) (int);

void foreach(struct node *list,func_t func)
{
   
 while (list != NULL) {
        func(list->
val);
        list = list->
next;
    }
}
void f(int n)
{
   
 printf("node(?) = %d\n",n);
}
int main(int argc, const char * argv[])
{

   
 @autoreleasepool {
       
       
 struct node *list = NULL,*l;
       
       
 for(int i=0;i<4;++i)
        {
            l =
 malloc(sizeof(struct node));
            l->
val = i;
            l->
next = list;
            list = l;
        }
       
       
 __block int i = 0;
        l=list;

        foreach(list, ^(int n){printf("node(%d) = %d\n",i++,l->val);});
       
    }
    return 0;
}

输出结果:
node(0) = 3
node(1) = 3
node(2) = 3
node(3) = 3
 
分析:
        1.重点看加粗的那行代码,我们可以看到使用block可以在调用foreach的时候直接将代码块作为foreach的第二个参数传入进去,而不像C语言中的函数调用那种远离foreach。

        2.在block中可以直接访问代码块外的局部变量i。(注:为了在代码块中改变i的值需要加__block修饰)


五 闭包的特性


1.作用域

       作用域即变量的可见范围,也就是某个变量可以被访问的范围,在C语言版的foreach函数无法实现的索引显示功能,而将block函数对象作为foreach第二个参数的时候,从block内可以访问外部的变量i,因此,从函数对象中能够访问外部变量进行访问(引用、更新),是闭包的构成要件之一。

2.生存周期

生存周期就是变量的寿命。看下面的例子:


typedef  void (^myBlock)(void );

myBlock extend()
{
   __block int n = 0;
  
   void (^myFunc)( void) = ^( void)
   {
       n++;
       NSLog(@"count=%d",count);
   };
   return [[myFunc copy] autorelease];  
}

int main(int argc, const char * argv[])
{
  
   @autoreleasepool {

       myBlock block = extend();
       block();
       block();
   }
   return 0;
}

        局部变量n是在extent函数中声明的,而extent函数已经执行完毕了。变量脱离作用域之后不是应该就消失了吗?不过就这个运行结果来看,即便函数执行完毕了,局部变量n貌似还在某个地方继续存货着。(注:上面的实例没有使用ARC,为了使返回的Block临时变量不被销毁延长其生命周期必须要要使用[myFunc copy],而为了最后的回收要使用autorelease)

        这个就是生命周期,也就是说,这个从属于外部(代码块外部)作用域中的局部变量,被函数对象给“封闭”在里面了。闭包这个词原来就是封闭的意思。被封闭起来的变量的寿命,与封闭它的对象寿命相等,也就是说,当封闭这个变量的函数对象不再被访问,被垃圾回收器回收掉时,这个变量的寿命也就终结了。

      现在大家明白了,将局部变量这一个环境封闭起来的结构被称为闭包。

    
    五 总结

        由上面的例子知道,当函数每次被执行时,作为隐藏上下文的局部变量n就会被引用和更新,也就是说,这意味着函数(过程)与数据结合起来了。
         “过程与数据的结合”是形容面向对象中“对象”时经常使用的表达。对象在数据中以方法的形式内含了过程,而闭包则是在过程中以环境的形式内含了数据。即对象和闭包是同一个事物的正反两个方面。
         
 
补充C++中函数对象

1.什么是函数对象        
    函数对象就是重载了“()”操作符的对象,也就是说如果一个类重载了“()”操作符,由它创建的对象就是函数对象。 因为函数对象本身是一个类的实例,因此它可以有自己的成员,这样,可以用这些成员保存一些普通函数不能轻易保存的(但可以通过静态局部变量和全局变量保存)的信息。同时,通过这个类的其他方法,可以对它的成员变量进行初始化和检查。 函数对象是比函数更加通用的概念,因为函数对象可以定义跨越多次调用的可持久的部分(类似静态局部变量),同时又能够从对象的外面进行初始化和检查(和静态局部变量不同)。
   例如:
int sum(int i, int j) { return i+j;      很可能它是一个函数对象:
class Sum {
public:
      int operator()(int i, int j) { return i+j; }
};
Sum sum;    而大多数情况是
template <class T>
class Sum {
public:
T operator()(T i, T j) { return i+j; }
};
Sum <int> sum;
在标准库中,函数对象被广泛地使用以获得弹性”,标准库中的很多算法都可以使用函数对象或者函数来作为自定的回调行为。
iOS开发中的Block使用示例 本文还有配套的精品资源,点击获取 简介:iOS开发中的Block是一个强大的编程工具,可以用来定义局部函数并作为参数或返回值。它简化代码并提高可读性,特别适用于回调和并发编程。本示例将帮助初学者掌握Block的基础用法,包括Block的定义、类型、变量捕获、作为参数和返回值的使用,以及copy行为和循环引用问题。此外,还会介绍Block在Grand Central Disp... 阅读详情

相关推荐

别再到处找资源了!WinCC 7.5 SP2官方下载与Windows 10保姆级安装避坑指南

本文提供了WinCC 7.5 SP2在Windows 10上的官方下载与安装全流程指南,重点解决了资源获取难、系统兼容性问题及分卷压缩处理等常见痛点。通过详细的步骤和实用技巧,帮助用户顺利完成安装并优化配置,适用于工控领域的学习者和从业者。

weixin_32924297的博客 478

iOS 教你如何使用代码块Block

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

H.A.N的博客 1373

基于粒子群算法的PID控制器优化设计

粒子群算法、PID、寻优

qq_46107700的博客 2万+

iOS 关于Block代码块的详解

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

LOLITA0164的博客 1万+

零信任架构实战:“持续验证+动态授权”全流程解析(附策略引擎联动图)

《零信任实战指南:7图拆解核心流程与行业案例》摘要:本文通过7张架构图系统解析零信任五大核心流程:强身份认证、设备检查、动态授权、持续监控和自动降权。对比金融(重数据审计)与制造业(重物理绑定)的落地差异,指出三大常见误区及解决方案。数据显示,零信任可使安全响应提速60%,泄露成本降低45%。文章提供6个月实施路线图,强调零信任是"智能信任"体系,建议企业分阶段改造,优先保护核心系统。附赠金融/制造行业策略模板及甘特图示例。(149字)

sara_han的博客 775

Microsoft Dynamics 365软件二次开发:Dynamics365部署与版本控制策略

在Microsoft Dynamics 365中,自定义实体允许开发者扩展系统以满足特定业务需求。自定义实体可以包含字段、选项集、关系和其他属性,与标准实体类似,但完全由用户定义。1. 登录到Dynamics 365环境。2. 转到“解决方案”区域,选择“自定义”。3. 在“自定义”菜单中,选择“实体”。4. 点击“新建”,输入实体名称,例如“客户反馈”。5. 添加字段,如“反馈类型”、“反馈日期”、“描述”等。6. 设置主键和唯一标识符。7. 定义关系,如与“客户”实体的关联。

kkchenjj的博客 2208

一篇文章看懂iOS代码块Block

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

蚊香酱的专栏 1万+

YOLOv12超参数智能优化:基于内置Ray Tune的自动化调优实战指南

购买即可解锁300+YOLO优化文章,并且还有海量深度学习复现项目,价格仅需两杯奶茶的钱,别人有的本专栏也有! 目标检测模型的性能瓶颈往往源于超参数配置不当。传统手动调优方式不仅耗时耗力,且难以找到全局最优解。YOLOv12集成的Ray Tune框架为解决这一难题提供了完整方案,通过分布式异步优化算法,可实现超参数搜索效率的指数级提升。实际测试表明,采用Ray Tune自动调优的YOLOv12模型,在COCO数据集上mAP指标平均提升3.8%,收敛速度加快2.1倍。在VisDrone无人机数据集上的跨域测试

LXY_LOVE36的博客 119

IOS开发 block(代码块)基本使用

1. block基本概念:(开篇废话) Block是C级别的语法和运行时特性。Block比较类似C函数,但是Block比之C函数,其灵活性体现在栈内存、堆内存的引用。Block是苹果推荐的类型,效率高,可以帮助我们组织独立的代码段,并提高复用性和可读性。主要是用来在运行中封装代码和保存代码用的。Block可以在任何时候被执行。和c语言的比较:1、可以保存代码。 2、有返回值。 3、有参数 4、调用

潇小溅 iOS技术专栏 2673

【GameFramework框架内置模块】1、全局配置(Config)

这是GameFramework框架内置模块的第一篇,全局配置Config,讲解这些模块的时候会尽量的涉及介绍、为什么使用、如何使用、代码分析这几块,让大家可以知其然,也知其所以然。全局配置表,存储了一些游戏中使用的全局的参数配置,比如玩家的初始速度、游戏初始音量等。全局配置表的结构跟DataTable结构类似,也是列行+键值对,只是没有ID这一列,因为全局配置也不需要用ID去查询, 是直接使用key值进行查询。

优快云博客专家,Unity3D高级软件工程师,《Unity 3D从入门到实战》作者。 5886

MNI152 坐标空间和 fsaverage 坐标空间相互转换, 如已知fsaverage空间的坐标如何求MNI152 坐标?aparc.a2009s.annot转化到MNI152空间?

大多数神经影像学研究的结果是在体积(例如,MNI152)或表面(例如,fsaverage)坐标系中报告的。体积坐标系和表面坐标系之间的准确映射可以促进许多应用,例如将 fMRI 组分析从 MNI152 投影到 fsaverage 以进行可视化或从 fsaverage 投影静息状态 fMRI 分区对 MNI152进行新数据的体积分析。Wu et al., 2018 评估了三种在 MNI152通过模拟上述应用的 Colin27 和 fsaverage 坐标系:将组平均数据从 MNI152/Colin27 投影到

从事脑科学核磁共振方法学研究,在Nature communications等权威期刊发表研究论文,熟练掌握磁共振处理方法和统计学方法,欢迎大家和我交流。 2966

[iOS] Block 的使用

Blocks是带有局部变量的匿名函数(不带名称的函数)。Blocks 也被称作闭包代码块。展开来讲,Blocks 就是一个代码块,把你想要执行的代码封装在这个代码块里,等到需要的时候再去调用。

2501_91494333的博客 1054

python中视觉检测怎么将多个面拍照的图片合成一个3d图像,用什么技术或者什么模型?

🏆本文收录于 《全栈Bug调优(实战版)》 专栏,该专栏专注于分享我在真实项目开发中遇到的各类疑难Bug及其深层成因,并系统提供高效、可复现的解决思路和实操方案。无论你是刚入行的新手开发者,还是拥有多年项目经验的资深工程师,本专栏都将为你提供一条系统化、高质量的问题排查与优化路径,助力你加速成长,攻克技术壁垒,迈向技术价值最大化与职业发展的更高峰🚀!

**My Coding Family** 709

IOS中block的声明定义和使用 一

对于IOS中Block得使用方法,以下我对Block的使用进行简单的介绍 1:首先声明一个Block指针 有参有返回值的Block的声明方式如下: 无参和无返回值的 void (^myBlock)(void); 有参有返回值的 int (^myBlock)(int,double); 总结: 返回类型  (^Block名称)(参数类型,...); 2:Block的定义 ^

Lucky Soldier 3859

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

iOS高级理论: Block介绍和使用

在 iOS 开发中,Block 是一种闭包(Closure)的概念,可以将一段代码块作为一个对象进行传递和存储,类似于函数指针。Block 可以捕获其定义时所在范围内的变量,并在需要的时候执行这段代码块。Block 的使用可以方便地实现回调、异步操作、事件处理等功能。

长沙火山 4263

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

ios之block代码块的简单使用 函数回调

// block 的简单使用demo 首先创建两个ViewController #import "RootViewController.h" #import "SencondViewController.h" typedef void(^myBlock)(int ,UIButton*); @interface RootViewController () { UILabel *label;

MR_ROG的专栏 1732

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

block代码块的使用

block 代码块功能类似于 delegate 代理。即也用来由 B 对象代理完成 A 对象的事件。 区别 1、不用定义协议(协议名称、协议方法、代理); 2、实现方法比较直观(实现代码比较紧凑,即代码块方法,紧接在对象实例化之后,避免多行空隔设置) 3、定义 block 属性对象时,应用 copy 类型,而定义 delegate 对象时应用 assign

番薯大佬的专栏 754

ios block使用

iOS Block的使用 一 .最简单的block使用**  使用block的三个步骤:1.定义block变量 2.创建block代码块 3.调用block匿名函数   定义一个block的构成包括:返回值,block名,参数类型。   block代码块作为一个匿名函数是可以被写在其他方法中的,所以一般我们将block代码块写在其他方法里,调用该方法的时候block代码块将不会被执行,只有回

lqk的博客 428

iOS代码块Block

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

plpldog的博客 2368

iOS之Block基本使用

来个大活,今天来写下Block 老方法,我们用WWW(what\why\how)进行学习block。 block是什么? block其实是一段代码块,其作用是保存一段代码块,在调用的时候block的时候,才调用里面的代码。 在程序里面输入inlineBlock,就可以得到block的声明与定义形式: /** 等号前面是block的声明; 等号后面是block的定义; returnType:b...

IOSSHAN的博客 664

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

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

weixin_39612677的博客 197

Objective-C的代码块(Block)

Objective-C中的代码块(Block)是iOS4.0和Mac OS X 10.6之后的系统中引进的对C语言的扩展。

痴_Pro的博客 2134

iOS之Block代码块的定义及使用

现在的无论是框架还是项目中,越来越多的使用block代码块。 个人觉得:第一可以使代码看起来更简单明了,第二可以取代以前的delegate使代码的逻辑看起来更清晰。 借一张图表达基本定义: (1)最基础的用法案例,可以把block理解为一段类似变量一样的可执行函数代码片段: void (^printBlock)(NSString *x);

LVXIANGAN的专栏 1万+

【iOS】 Block再学习

笔者之前学习过block的相关内容,但是掌握不牢,今天再重新学习一遍。

qq_73106050的博客 1604

iOS方法中block使用

iOS中Block的使用 在iOS开发中,Block是一种非常强大的语法特性,它提供了对代码块的封装,使我们能够灵活地进行回调、事件处理和数据传递。本文将基于Block的基本用法,通过代码示例和详细解释,帮助您更好地理解Block在iOS中的应用。 什么是Block? Block是一个可以在应用程序中定义和执行的自包含代码...

weixin_41280043的博客 170
上一篇: Protocol Buffers 的使用 (一)
下一篇: ZeroMQ 使用(一)
张哲BJUT
博客等级 码龄15年 151粉丝 111原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值