博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Objective-C之Block
阅读量:6040 次
发布时间:2019-06-20

本文共 3318 字,大约阅读时间需要 11 分钟。

hot3.png

Block基本概念

本小节知识点:

  1. 【了解】什么是Block
  2. 【理解】block的格式

1.什么是Block

  • Block是iOS中一种比较特殊的数据类型

  • Block是苹果官方特别推荐使用的数据类型, 应用场景比较广泛

    • 动画
    • 多线程
    • 集合遍历
    • 网络请求回调
  • Block的作用

    • 用来保存某一段代码, 可以在恰当的时间再取出来调用
    • 功能类似于函数和方法

2.block的格式

  • Block的定义格式
返回值类型 (^block变量名)(形参列表) = ^(形参列表) {};

  • block最简单形式
void (^block名)() = ^{代码块;}例如:void (^myBlock)() = ^{ NSLog(@"李南江"); };
  • block带有参数的block的定义和赋值
void (^block名称)(参数列表)= ^ (参数列表) { // 代码实现; }例如:void (^myBlock)(int) = ^(int num){ NSLog(@"num = %i", num); };
  • 带有参数和返回值的block
返回类型 (^block名称)(参数列表)= ^ (参数列表) { // 代码实现; }例如:int (^myBlock)(int, int) = ^(int num1, int num2){ return num1 + num2; };
  • 调用Block保存的代码
block变量名(实参);

block和typedef的使用

 

C语言的指向函数指针用法

#import 
int sum(int value1,int value2){ return value1 + value2;}int minus(int value1,int value2){ return value1 - value2;}int main(int argc,onst char * argv[]){ int (*sumP)(int,int); sumP = sum; NSLog(@"sum = %i",sumP(20,10)); int (*minusP)(int,int) minusP = minus; NSLog(@"minus = %i",minusP(20,10)); return 0;}

由于相同的部分可以抽离出来,所以需要使用typedef

#import 
int sum(int value1,int value2){ return value1 + value2;}int minus(int value1,int value2){ return value1 - value2;}typedef int (*calculte)(int,int)int main(int argc,onst char * argv[]){ calculte sumP = sum; NSLog(@"sum = %i",sumP(20,10)); calculte minusP = minus; NSLog(@"minus = %i",minusP(20,10)); return 0;}

OC的block的用法

#import 
int main(int argc,onst char * argv[]){ int (^sumBlock)(int,int); sumBlock = ^(int value1,int value2){ return value1 + value2; }; NSLog(@"sum = %i",sumBlock(20,10)); int (^minBlock)(int,int); minBlock = ^(int value1,int value2){ return value1 - value2; }; NSLog(@"min = %i",minBlock(20,10)); return 0;}

使用typedef之后:

#import 
typedef int (^calculteBlock)(int,int);int main(int argc,onst char * argv[]){ calculteBlock sumBlock = ^(int value1,int value2){ return value1 + value2; }; NSLog(@"sum = %i",sumBlock(20,10)); calculteBlock minBlock = ^(int value1,int value2){ return value1 - value2; }; NSLog(@"min = %i",minBlock(20,10)); return 0;}

block的应用场景

 

在学习UI之后就会体会到block的好处。

这段代码要多练习,练习到不用看源码就能熟练敲出来。

#import 
void Hello(void (^func)()){ NSLog(@"Hello Wrold~"); func(); NSLog(@"Hello HeYang~");}void sayHello(){ Hello(^{ NSLog(@"Hello World,Hello HeYang~"); });}int main(int argc, const char * argv[]) { @autoreleasepool { sayHello(); } return 0;}

举个block应用实例场景:

需求:    找到需要读取并需要操作的文件步骤:    读取文件    操作文件    关闭文件分析:    其中读取文件和关闭文件都是一样的    而操作文件,会根据需求而变化,或者根据文件类型而不一样总结:    这里就需要使用block把操作文件的功能分离出来。

将Objc的m文件编译成C++文件的终端命令:

cc -rewrote-objc xx.m(OC的m文件)

然后在当前目录下就会出现后缀cpp的C++文件。

block是存储在堆中还是在栈中?默认情况下block存储在栈中,如果对block进行一个copy操作,block会转移到堆中如果block在栈中,block中访问了外界的对象,那么不会对对象进行retain操作但如果是block在堆中,block中访问了外界的对象,那么会对外界的对象进行一次retain

在MRC模式下,我们分析一下是不是会出现内存泄露

Person *p = [[Person alloc]init];NSLog(@"retainCount = %lu",[p retainCount]);void (^myBlock)() = ^{    NSLog(@"a = %@",p);    NSLog(@"block retainCount = %lu",[p retain]);}Block_copy(myBlock);myBlock();

如果在block中访问了外界的对象,一定要给对象加上__block,只要加上了__block,哪怕block在堆中,也不会对外界的对象进行retain。

加了__block就是地址传递,不加__block是值传递。正因为是值传递,所以可以访问其值,或者return返回其值。

转载于:https://my.oschina.net/u/2363463/blog/635918

你可能感兴趣的文章
MySQL内核技术之“WHERE条件”
查看>>
Laravel 学习笔记之 request validation
查看>>
electron+vue制作桌面应用--自定义标题栏最大/小化和关闭
查看>>
Java IO初探
查看>>
webpack使用笔记
查看>>
【292天】每日项目总结系列030(2017.11.24)
查看>>
前端每周清单半年盘点之 WebAssembly 篇
查看>>
一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](一)
查看>>
JavaScript专题之函数组合
查看>>
Base64 编码的编程使用.md
查看>>
Maven 打包发布到nexus
查看>>
前端学习资料
查看>>
[Android刷新过程]Zenfone2 z00ada EML551 ,Moto nexus 6
查看>>
PHPer这样写代码也许更优雅
查看>>
CoordinatorLayout的使用
查看>>
小程序入门案例教学 - 手机归属地查询
查看>>
我的面试准备过程--leetcode树
查看>>
php运行出现Call to undefined function curl_init()
查看>>
Rancher被Gartner评为“四大最酷云基础设施供应商”之一!
查看>>
CSS 研究所 - 收藏集 - 掘金
查看>>