闭包与 Objective-C block | 青训营笔记

211 阅读2分钟

这是我参与「第四届青训营」笔记创作活动的第5天

一、本堂课重点内容:

image.png

二、详细知识点介绍:

1.闭包基础

1).闭包的基本定义

闭包本身是一个结构体,存储了函数入口地址和与之绑定的一系列环境,环境里面既有其本身内部定义的变量,又包含从外部捕获的变量,捕获变量的处理因实现而异。 image.png

2).闭包在C++11中的表现形式

#include <algorithm>
#include <cmath>

void abssort(float* x, unsigned n) {
    // 按绝对值大小排序
    std::sort(x, x + n,
        // Lambda expression begins
        [](float a, float b) {
            return (std::abs(a) < std::abs(b));
        } // end of lambda expression
    );
}

2.Block基础

1).基础概念

  • block是闭包在Objective-C中的实现
  • block可以接受参数也可以有返回值
  • block可以分配在栈和堆上,也可以是全局的。分配到栈上的块可以拷贝到堆中,同标准的Objective-C对象一样,具备引用计数(这里大家可以简单回顾下上节课内容,Objective-C中是如何利用引用计数实现ARC的,会有关联的内容)

2).标准格式

// block声明
// 返回值 (^block的名称)(block传入的参数)
returnType (^blockName)(parameters);

// block赋值
// ^返回值(block传入的参数)
^returnType(parameters) {
  // do something;
};

// 示例:求和
int (^sumBlock)(int a, int b) = ^int(int a, int b) {
    return a + b;
};
int sum = sumBlock(1, 1);

3).常用简写

// 有返回值有入参
int (^sumBlock)(int, int) = ^(int a, int b) {
    return a + b;
};

// 无返回值无入参
void (^printBlock)(void) = ^{
    NSLog(@"Hello World!");
};

//typedef 定义别名
typedef returnType (^blockName)(parameters);
//示例
typedef int (^SumBlock)(int a, int b);
SumBlock block = ^(int a, int b) {
    return a + b;
};
int sum = sumBlock(1, 1);

3.Block内存管理

1).基础分类

类型描述环境
NSGlobalBlock全局Block,保存在数据区(.data段)定义在全局区或者没有访问自动局部变量
NSStackBlock栈Block,保存在栈区访问了自动局部变量
NSMallocBlock堆Block, 保存在堆区__NSStackBlock__调用了copy
//三类Block
int main(int argc, char * argv[]) {
    @autoreleasepool {
        // __NSGlobalBlock__
        void(^globalBlock)(void) = ^{
            NSLog(@"Hello, World!");
        };
        NSLog(@"%@", [globalBlock class]);

        // __NSStackBlock__
        int age = 18;
        void(^stackBlock)(void) = ^{
            NSLog(@"Hello, World! %d", age);
        };
        NSLog(@"%@", [stackBlock class]);

        // __NSMallocBlock__
        void(^mallocBlock)(void) = [stackBlock copy];

        NSLog(@"%@", [mallocBlock class]);
    }
    return 0;
}

2).变量捕获

- (void)changeValue {
    int value = 1;

    void (^oneBlock)(void) = ^{
        NSLog(@"value = %d", value); // value1:?
    };

    value = 2;
    oneBlock();
    NSLog(@"value = %d", value); // value2:?
}

3).内存泄漏的产生与修复

4.Block应用

1).数组遍历

2).网络请求中数据传递

3).链式调用

4).多线程中调用

三、实践练习例子:

  • 有什么实践举例帮助理解知识点?

四、课后个人总结:

  • 本章有什么知识点不容易掌握?

  • 什么地方容易与其他内容混淆?

五、引用参考:

学习手册:juejin.cn/post/712344…
课程PPT:闭包与 Objective-C block.pptx