ios学习笔记——Block块小结

本文详细介绍了Objective-C中块的基础知识,包括定义、使用、内部结构及如何正确捕获变量等内容。通过示例展示了如何在块中修改变量,并解释了块作为对象的引用计数机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、块的基础知识


块与函数类似。尤其跟函数指针非常相思,用法也大同小异。

块的语法结构如下:

return_type  (^block_name)(parameters)

返回类型    块名称    参数

1     //定义块
2     int (^sjzBlock)(int a, int b) = ^(int a, int b){
3         return a + b;
4     };
5     //使用块
6     int c = sjzBlock(1, 2);

 

在声明块的范围内,所有变量都可以为其所捕获。但是不能修改变量,如果想要修改,可以在声明变量的时候加上__block修饰符。

 1     //在块里修改e的值,报错
 2     int e = 100;
 3     //加上__block修饰符,可以修改d的值
 4     __block int d = 10;
 5     int (^sjzBlock)(int a, int b) = ^(int a, int b){
 6         d = 12;
 7 //        e = 90;  //报错
 8         return a + b;
 9     };
10     int c = sjzBlock(1, 2);
11     NSLog(@"c = %d  d = %d", c, d);

输出结果:

 

块本身也是一个对象,也有引用计数。

如果块所捕获的变量是对象类型,那么就会自动保留它。系统在释放这个块的时候,也会将其一并释放。

块可以访问类的所有实例变量,块能够修改实例变量,所以在声明实例变量时,无需加__block。如果通过读取或写入操作捕获实例变量,那么也会自动把self变量一并捕获了,因为实例变量是与self所只带的实例关联在一起的。当块保留self的时候,很可能self也保留了块,容易造成循环引用。

 1 #import "ViewController.h"
 2 
 3 @interface ViewController ()
 4 
 5 @property (nonatomic, strong) NSString * sjzStr;
 6 
 7 @end
 8 
 9 @implementation ViewController
10 
11 - (void)viewDidLoad {
12     [super viewDidLoad];
13     
14     [self blockText];
15 }
16 
17 - (void)blockText
18 {
19     void (^sjzBlock)(int a, int b) = ^(int a, int b){
20         //以下这两种调用,都会将会捕获self
21 //        _sjzStr = @"Hello, world";
22         self.sjzStr = @"hello, world";
23         NSLog(@"%@", _sjzStr);
24     };
25     
26     sjzBlock(1, 2);
27 }
28 
29 @end

 

 

块的内部结构


 

这里面,最重要的是invoke变量,是一个函数指针,指向块的实现代码。至少接受一个void*类型的参数,此参数代表块本身。

descriptor变量是指向结构体的指针,每个块都包含改结构体。声明了块的总体大小,copy函数指针保留捕获的对象,dispose当块释放时,释放捕获的对象。

块会把它捕获的对象全部拷贝一份,捕获了多少对象,就要占据多少内存空间。

转载于:https://www.cnblogs.com/sjzlovecj/p/5261043.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值