block与GCD--37:块

2023-11-22 08:29:14 浏览数 (2)

block的基础知识

  • Block是一种特殊的数据类型(快速实现直接输入inlink)

Block的格式

代码语言:javascript复制
返回值(^block变量名)(形参列表) =  ^( 形参列表){

};
  • 无参数无返回值
代码语言:javascript复制
void (^sunBlock)();
sunBlock = ^{
  NSLog(@"sunBlock");
};
sunBlock();
  • 有参数无返回值
代码语言:javascript复制
void(^sunBlock)(int,int);
sunBlock = ^(int value1,int value2){
    NSLog(@"%d",value1   value2);
};
sunBlock(10,20);
  • 有参数有返回值
代码语言:javascript复制
int (^sunBlock)(int,int);
sunBlock = ^(int value1,int value2){
    return value1   value2;
};
NSLog(@"%d",sunBlock(10,20));

块的内部结构

块对象内存布局

在块对象的内存区域中

  • 首个变量指向所属类的指针(isa),也就是block的类型
  • invoke变量是一个函数指针,指向块的实现代码
  • descriptor变量是指向结构体的指针,其中声明了块对象的总体大小,还声明了copy与dispose辅助函数所对应的函数指针,辅助函数在拷贝或丢弃块对象时运行
  • 块会把它所捕获的所有变量copy一份,拷贝的并不是对象本身,而是指向这些对象的指针变量。

块的分类

全局的静态 block:NSConcreteGlobalBlock,不会访问任何外部变量。 栈中的 block:NSConcreteStackBlock,当函数返回时会被销毁。 堆中的 block:NSConcreteMallocBlock,当引用计数为 0 时会被销毁。

  • 全局块
代码语言:javascript复制
void (^testGlobalBlock)() = ^{
    NSLog(@"hello block");
};
int main(int argc, const char * argv[]) {
    testGlobalBlock();
    return 0;
}
  • 栈块
代码语言:javascript复制
int main(int argc, const char * argv[]) {
    void (^testStackBlock)() = ^{
        NSLog(@"hello block");
    };
    testStackBlock();
    return 0;
}
  • 堆块(给块发送copy消息就可以把block复制到堆中)
代码语言:javascript复制
int main(int argc, const char * argv[]) {
   void (^testStackBlock)() = [^{
        NSLog(@"hello block");
    } copy];
    testStackBlock();
    return 0;
}

0 人点赞